HAProxy Enterprise Documentation 2.4r1

Release Notes

New and/or improved features in HAProxy Enterprise 2.4r1 include:

Enterprise Suite

Advanced WAF

ModSecurity WAF

Global Profiling Engine

The Global Profiling Engine is a drop-in replacement for the Stick Table Aggregator, with the ability to aggregate stick table data from across a cluster of load balancers in real time. It can also aggregate historical data over a timespan. For example, you can store the average HTTP request rate over an entire day and then calculate statistics from it automatically, such as averages and percentiles, which enables you to alter rate limiting thresholds dynamically based on average traffic load at a given time of day. This simplifies the task of setting rate limit thresholds, making the experience more adaptive and turnkey.

Improved reloading of map files

Map files now reload faster.

Arm packages

Packages that target Arm processors on Ubuntu 20.04 were added.


Protocol support

HTTP/2 WebSockets

Support for the WebSocket protocol over HTTP/2 through the extended CONNECT HTTP method, which is outlined in RFC 8441, allows multiple WebSocket tunnels to share a single TCP connection.

Financial Information eXchange (FIX)

HAProxy Enterprise can now accept, validate, and route FIX protocol messages. FIX is an open standard that has become the de facto protocol in the Fintech world. HAProxy Enterprise can also inspect tag values within the Logon message sent by the client, which you can use to make authorization and routing decisions using ACLs.


MQTT is a lightweight messaging protocol typically used for communicating with Internet of Things (IoT) devices. you can use the mqtt_is_valid converter to check whether the first message sent by the client (a CONNECT message) or by the server (a CONNACK message) is a valid MQTT packet. You can also read the fields in those initial messages to perform an authorization check and/or initialize session persistence to a server. Also, the mqtt_field_value converter reads a field from a CONNECT or CONNACK message.

Load Balancing

DNS TCP resolution

The resolvers section now allows listing DNS servers over TCP, which supports larger DNS responses. HAProxy Enterprise will accept TCP responses as large as 65,535 bytes. Prefix the nameservers addresses with tcp@.

Circuit breaking

New stick table counters named http_fail_cnt and http_fail_rate track server-side, HTTP 5xx errors. You can use these in circuit breaking to disable a backend server if it returns too many errors.

SSL/TLS improvements

Dynamic SSL Certificate Storage (Server side)

The Runtime API commands show ssl cert, set ssl cert, and commit ssl cert can now be applied to certificates referenced by server lines in a backend. You can now also take advantage of ssl-load-extra-files and ssl-load-extra-del-ext directives in your backend section to allow storing your certificate’s private key in a separate file from the certificate itself.

Connection reuse improvements

When a connection is handled over TLS, many connections need to be marked private (for example, when sending SNI) to prevent reusing the wrong information (e.g. wrong SNI). That prevents a connection from being reused in many cases. With this release, connections to backend servers can now be reused even when the SNI is calculated dynamically, such as from the request’s Host header (e.g. sni req.hdr(host)).

SSL/TLS statistics

When you add stats show-modules to your stats frontend, it adds a new column called Extra modules to the page that shows HTTP/2 related statistics. HAProxy Enterprise 2.4 adds more fields there for tracking SSL/TLS handshake and session statistics.

You will find the following new fields, which are also displayed when you call the Runtime API’s show stat command, given you have at least one bind statement that terminates SSL:




Total number of SSL sessions established


Total number of SSL sessions reused


Total number of failed handshake


Built-in OpenTracing

OpenTracing is now compiled directly into the core codebase.

Prometheus metrics

State values for frontends, backends, and servers (up, down, maint, etc.) have been changed from being gauge values to being labels, making it easier to group by this criteria.

New metrics have been added to report on listeners, stick tables, and backend/server weight information, which we list below:

  • haproxy_process_uptime_seconds

  • haproxy_process_recv_logs_total

  • haproxy_process_build_info

  • haproxy_listener_current_sessions

  • haproxy_listener_max_sessions

  • haproxy_listener_limit_sessions

  • haproxy_listener_sessions_total

  • haproxy_listener_bytes_in_total

  • haproxy_listener_bytes_out_total

  • haproxy_listener_requests_denied_total

  • haproxy_listener_responses_denied_total

  • haproxy_listener_request_errors_total

  • haproxy_listener_status

  • haproxy_listener_denied_connections_total

  • haproxy_listener_denied_sessions_total

  • haproxy_listener_failed_header_rewriting_total

  • haproxy_listener_internal_errors_total

  • haproxy_backend_uweight

  • haproxy_server_uweight

  • haproxy_sticktable_size

  • haproxy_sticktable_used


Vary header

This release brings support for the Vary header via a new keyword process-vary, which is set to on or off. It defaults to being off, which means that a response containing a Vary header will simply not be cached. It will also automatically normalize the accept-encoding header to improve the use of the cache.

Also, a new directive max-secondary-entries allows you to control the maximum number of cached entries with the same primary key. For example, if you cache based on URL, but vary on the user-agent, you may create a lot of slightly different cached entries for the same URL. This prevents the cache from being filled with duplicates of the same resource. It requires process-vary to be on and it defaults to 10.



New, nestable, preprocessor-like directives allow you to include or skip some blocks of configuration markup.

The following directives have been introduced to form conditional blocks:

  • .if <condition> ... .endif

  • .elif <condition>

  • .else

  • .diag

  • .notice

  • .warning

  • .alert

The .if and .elif statements are followed by a function name, such as:

.if version_atleast(2.4)
   # include configuration lines

Available functions are:




returns true if an environment variable <name> exists, regardless of its contents


returns true if feature <name> is listed as present in the features list reported by haproxy -vv


returns true if the two strings are equal


returns true if the two strings differ


returns true if the current HAProxy version is at least as recent as <ver> otherwise false


returns true if the current HAProxy version is strictly older than <ver> otherwise false

Also, the following pre-processor directives can be placed inside a conditional block:



.diag "message"

emit this message only when in diagnostic mode (-dD)

.notice "message"

emit this message at level NOTICE

.warning "message"

emit this message at level WARNING

.alert "message"

emit this message at level ALERT

Default path

A new global directive default-path allows you to specify the path from which you would like HAProxy Enterprise to load additional files, such as map and ACL files. It accepts one of the following options:




Relative file paths are loaded from the directory the process was started in. This is the default.


Relative file paths are loaded from the directory containing the configuration file.


Relative file paths should be loaded from the parent directory above the configuration file directory.

origin <path>

Relative file paths should be loaded from the designated path.

Pseudo variables

Pseudo-variables have been added, which can be helpful when troubleshooting.




the name of the configuration file currently being parsed.


the line number of the configuration file currently being parsed, starting at one.


the name of the section currently being parsed, or its type if the section doesn’t have a name (e.g. "global")

Named defaults sections

You can now assign a name to a defaults section and inherit its settings specifically in a frontend or backend.

defaults http-defaults
  # default settings ...

frontend fe_http from http-defaults
  # inherits the settings

You can also extend a named defaults section from another defaults section:

defaults tcp-defaults
  mode tcp
  timeout connect 5s
  timeout client 5s
  timeout server 5s

default http-defaults from tcp-defaults
  mode http
Dynamic server timeouts

You can change the timeout server and timeout tunnel settings dynamically using the http-request set-timeout directive. You can use this to set custom timeouts on a per-host or per-URI basis, pull a timeout value from an HTTP header, or change timeouts using a Map file.

The following fetches are available:




Returns the configuration value in millisecond for the server timeout of the current backend


Returns the configuration value in millisecond for the tunnel timeout of the current backend


Returns the currently applied server timeout in millisecond for the stream


Returns the currently applied tunnel timeout in millisecond for the stream

HTTP protocol upgrade

The new tcp-request content switch-mode directive upgrades a mode tcp connection to mode http dynamically. Combined with the built-in HTTP ACL, you can switch to mode http if the traffic is HTTP.

frontend fe_main
   mode tcp
   tcp-request inspect-delay 5s
   tcp-request content switch-mode http if HTTP
Header deletion with pattern matching

The http-request del-header, http-response del-header, and http-after-response del-header directives now support the argument -m <method> to delete a header based on a matched pattern.

HTTP request conditional body wait time

The new http-request wait-for-body and http-response wait-for-body directives allow you to conditionally wait for and buffer a request or response body. These actions may be used as a replacement for option http-buffer-request.

In the snippet below, HAProxy Enterprise waits one second at most to receive the POST body of the request, or until it gets at least 1,000 bytes:

http-request wait-for-body time 1s at-least 1k if METH_POST

New fetches and converters


This table lists new fetches:




Returns the concatenation of the first Host header and the path part of the request with the query-string, which starts at the first slash


This is the destination ip address of the connection on the server side, which is the server address HAProxy connected to.


Returns an integer value corresponding to the destination TCP port of the connection on the server side, which is the port HAproxy connected to.


This is the source ip address of the connection on the server side, which is the server address haproxy connected from.


Returns an integer value corresponding to the TCP source port of the connection on the server side, which is the port HAproxy connected from.


Returns the configuration value in millisecond for the server timeout of the current backend


Returns the configuration value in millisecond for the tunnel timeout of the current backend


Returns the currently applied server timeout in millisecond for the stream


Returns the currently applied tunnel timeout in millisecond for the stream


Returns the configuration value in millisecond for the client timeout of the current frontend


Returns the cumulative number of HTTP response failures from the currently tracked counters. This includes the both response errors and 5xx status codes other than 501 and 505.


Returns the average rate of HTTP response failures from the currently tracked counters, measured in amount of failures over the period configured in the table. This includes the both response errors and 5xx status codes other than 501 and 505. See also src_http_fail_rate.


Returns the DER formatted certificate presented by the client when the incoming connection was made over an SSL/TLS transport layer


The following converters have been added:




The json_query converter supports the JSON types string, boolean and number.


Hashes a binary input sample into a signed 64-bit quantity using the XXH3 64-bit variant of the XXhash hash function


This converter is the base64url variant of b64dec converter. base64url encoding is the “URL and Filename Safe Alphabet” variant of base64 encoding. It is also the encoding used in JWT (JSON Web Token) standard.


This converter is the base64url variant of base64 converter.


Takes a string provided as input and returns the encoded version as output

Runtime API

This version includes the following changes to the Runtime API:

Help filtering

The help command will attempt to display information for partially spelled commands.

Also if you enter an incorrect command, the API will suggest alternatives.


This release adds two new Runtime API commands.



set server <backend>/<server> agent-port <port>

Change the port used for agent checks.

set server <backend>/<server> check-addr <ip4 | ip6> [port <port>]

Change the IP address used for server health checks. Optionally, change the port used for server health checks.

set server <backend/server> ssl on

Activates SSL on outgoing connections to a server at runtime.

prepare acl

Begin a transaction for adding ACLs. This returns a number, which you would then reference in the add acl command.

commit acl

Commit the transaction to add new ACLs.


Lua has been extended to support multithreading. A new global directive, lua-load-per-thread, has been added to aid with this. For Lua scripts that require threading, this should be used as it will launch the Lua code as an independent state in each thread. The existing lua-load keyword still exists and should be used for Lua modules meant to cover the entire process, such as jobs registered with core.register_task.


There are the following miscellaneous changes:

  • The tune.chksize directive has been deprecated.

  • During a reload, processes are closed sooner, rather than waiting for idle frontend connections to timeout.

  • During a reload, idle backend connections are actively killed.

  • TCP log outputs now automatically create a ring buffer.

  • Layer 7 retries now support 401 and 403 HTTP status codes.

  • The http-check send directive now supports adding a Connection header.

  • The global section now supports setting process level variables.

  • A new macro HTTP_2.0 has been added, which will return true for HTTP/2 requests.

  • The server-state-file-name directive has a new argument, use-backend-name, that allows you to load the state file using the name of the backend. This only applies when the directive load-server-state-from-file is set to local.

  • A new srvkey parameter has been added to the stick-table directive. This allows you to specify how a server is identified. It accepts either name, which will use the current defined name of the server or addr, which will use the current network address including the port. addr is useful when you are using service discovery to generate the addresses.

  • A new log-format parameter, %HPO, was added, which allows logging of the request path without the query string.

Next up

Getting Started
HAProxyConf 2022 - Call for papers