Hi,
HAProxy 3.1.9 was released on 2025/10/03. It added 149 new commits
after version 3.1.8.
As promised in the 3.1.9 announce, here is the usual description of bugs
fixed by this release:
* The most important one is obviously the mjson JSON decoder issue
described in the previous mail. Decoding of numbers with large exponents
was eating a lot of CPU and could even trigger the watchdog and kill the
process. "json_query()", "jwt_header_query()", and "jwt_payload_query()"
converters was affected. This bug was assigned CVE-2025-11230 and
affected all versions featuring the JSON decoder, or 2.4 and above.
* In the QUIC part, a crash could occur on the sending path because of a
too protective BUG_ON() when the QUIC stream was waiting for a buffer to
emit data. This case is in fact legitimate and may happen for instance
during reload. Now a send failure is returned, waiting to be able to get
a buffer to proceed. Another crash on a BUG_ON() was possible because
INITIAL packets were not always padded to 1.200 bytes as they should
be. It was possible to block a QUIC connection on the handshake parsing
after having received two Initial packets. Packet padding was not
properly reset when GSO was in use. There were few issues in the CRYPTO
frames parsing. PING and CONNECTION_CLOSE could be mixed, which is
useless. It was possible to coalesce probing and ACK packet of same
type. QUIC listeners on FreeBSD were not functional if bound on a
specific address. The upper multiplexer layer and HTTP/3 was also
improved to now properly deal with HTTP 1xx interim responses. Using a
QUIC address format on a server line is inappropriate and should be
rejected (and now is). An erroneous encoding of QUIC frame type
CONNECTION_CLOSE resulted in CONNECTION_CLOSE_APP instead to be emitted.
All these issues were fixed.
* An old bug were revealed about synchronous write events than could be
missed during the data processing. This issue could lead to freeze a
session until the next I/O event or a timeout expiration. The issue was
fixed but it remains a bit sensitive.
* H2 on backend side could mishandle a connection error before the preface
and cause a wakeup loop while data from other streams were waiting to be
evacuated to the client. It caused a loop and a crash reported for the
first time in issue #3020 though it's been there since backend H2 is
supported.
* In both H2 and H3, the 'Z' character (in upper case) was not rejected as
expected from header field names. Thanks to @zhanhb, it now fixed.
* We've also addressed the detection of forbidden chars in the Host
header in H1, H2 and H3.
* It was possible to not respect healthchecks timeout when the "check"
timeout was defined with a high "connect" timeout. In that case, the
check task was not woken up as expected on timeout expiration.
* An old issue about the FD insertion in the fdtab array was revealed by
the recent changes to support different CPU alloocation policies. The
wrong thread group was used and depending on the mapping, this could
lead to a crash.
* On server side, a configured SNI could be used as pool name for idle
connections for non-SSL servers. While this kind of configuration is
unlikely, it could result of inheritance of some default parameters. In
that case, the connection reuse could be totally inoperative.
* There was an issue when loading CA certificates from a directory. Only
the first certificate of each file was loaded. It was an issue on some
systems (debian/ubuntu ones were not affected). The issue was fixed by
using X509_STORE_load_locations() on each file instead of loading
certificates by hand.
* The documentation of 'accept-unsafe-violations-in-http-request' option
was fixed to properly describe checks performed on the URI during the
request parsing.
* In the SPOP multiplexer, there was a possible NULL-pointer dereference
on SPOP stream allocation failure. And a crash could be encountered with
the SPOE if a parent stream aborted while the connection to the agent
was queued. This happened because the applet responsible to handle the
SPOE stream was released without interrupting the connection attempt. In
addition, since the SPOE refactoring, empty NOTIFY frames were no longer
skipped and were sent to the agent. Those frames are now properly
ignored.
* The %ID log alias was not suitable for use in unique-id-format
construction, where it would cause an infinite recursive loop during
evaluation. Now it will detect the situation and evaluate to empty in
this case. In addition, the evaluation of the ID is now made closer to
where it's evaluated so as to avoid inconsistencies (e.g.
unique-id-format referencing elements not available at log production
time).
* L6/L7 sample fetch functions cannot be used in Lua services since they
don't have access to the channel, yet L6 was not rejected, possibly
wasting time when users would try to implement them and figure why they
don't work.
* A risk of wakeup loops on CLI commands with output full was addressed.
It could consume lots of CPU while waiting, possibly leading to a crash
(though not reported since 3.0 where the issue appeared).
* The use of unsetenv() to clear the environment when re-execing was not
reliable due to "environ" being suject to change on some OS in this case
(e.g. illumos). This was fixed by using our dedicated function.
* In the SSL stack, a regression in certificate selection was fixed which
could cause issue if haproxy was configured with TLS 1.2 as maximum
version supported. Early-data support on the backend side was adjusted
as it was broken for some time now, as no data could be emitted prior to
the handshake completion.
* The httpclient was progressively refined as its usage is becoming more
prevalent. Most notably, it is able to deal better with large transfers.
It can also now properly handle interim and early HTTP responses.
* On the LUA side, server iterator usage could cause a crash. Also, read
and write events are properly notify when using the socket class to
avoid infinite wait when the write side has been blocked earlier.
* For resolvers, a delay tempo was previously introduced between two
connections attemps to a DNS server. However, this could result in an
important CPU consumption due to a rescheduling in loop of the
connection task. Now, the timer is properly resetted after a successful
connection which is enough to solve the issue.
* The error reported by the master process when a worker crashes during
its configuration parsing was improved to include the PID of the worker
and the exist status code. In addition, because of an issue with the
sockpair protocol on macOS
(https://man.freebsd.org/cgi/man.cgi?sendmsg(2)), the startup/reload was
no longer working and this since the master-worker rework. This was
fixed by using a blocking read in the master to receive the
acknowledgment from the worker before closing the recv fd on the sending
side. However, the same issue exists on the master CLI. Unfortunately no
solution was found on macOS.
* Several OOM checks was added here and there by Alexander Stephan.
* In the rings, a crash because of a BUG_ON() was possible because of an
integer overflow on the message size that could lead to emit messages
bigger than the maximum ring size. This was fix by changing the message
size comparison to avoid any overflow.
* A crash could be experienced if a certificate or a CA was updated on the
CLI while an OCSP response was being updated by corrupting the update
tree. This tree is now protected by a lock.
* The normalization of FQDNs from resolvers response was not properly
performed. It was fixed by converting them to lower case.
* The ALPN used to perform healthchecks over SSL is now properly inherited
from server settings when no "check-alpn" directive is used. This could
lead to healthchecks failure for servers relying explicitly on H2. And a
Use-After-Free was possible if a "check-alpn" parameter inherited from
the default server was overridden on the server line because the default
value was released, preventing any reuse by another server.
* Errors could be erroneously reported during the configuration parsing
when the same virtual map (with 'virt@' prefix) was used at diffrent
places. In addition, optional maps (with 'opt@' prefix) were not
properly referenced. The prefix was not removed from the map name as
expected. Both issues were fixed.
In addition to these fixes, the "ssl_bc_sni" sample fetch function was
backported. It can be useful during debugging sessions to know what SNI was
configured on a connection going to a server, for example to match it
against what the server saw or to detect cases where a server would route on
SNI instead of Host.
Thanks everyone for your help !
Please find the usual URLs below :
Site index : https://www.haproxy.org/
Documentation : https://docs.haproxy.org/
Wiki : https://github.com/haproxy/wiki/wiki
Discourse : https://discourse.haproxy.org/
Slack channel : https://slack.haproxy.org/
Issue tracker : https://github.com/haproxy/haproxy/issues
Q&A from devs : https://github.com/orgs/haproxy/discussions
Sources : https://www.haproxy.org/download/3.1/src/
Git repository : https://git.haproxy.org/git/haproxy-3.1.git/
Git Web browsing : https://git.haproxy.org/?p=haproxy-3.1.git
Changelog : https://www.haproxy.org/download/3.1/src/CHANGELOG
Dataplane API :
https://github.com/haproxytech/dataplaneapi/releases/latest
Pending bugs : https://www.haproxy.org/l/pending-bugs
Reviewed bugs : https://www.haproxy.org/l/reviewed-bugs
Code reports : https://www.haproxy.org/l/code-reports
Latest builds : https://www.haproxy.org/l/dev-packages
---
Complete changelog :
Alexander Stephan (6):
BUG/MINOR: halog: Add OOM checks for calloc() in
filter_count_srv_status() and filter_count_url()
BUG/MINOR: log: Add OOM checks for calloc() and malloc() in logformat
parser and dup_logger()
BUG/MINOR: acl: Add OOM check for calloc() in smp_fetch_acl_parse()
BUG/MINOR: cfgparse: Add OOM check for calloc() in cfg_parse_listen()
BUG/MINOR: compression: Add OOM check for calloc() in
parse_compression_options()
BUG/MINOR: tools: Add OOM check for malloc() in indent_msg()
Amaury Denoyelle (29):
BUG/MINOR: config/server: reject QUIC addresses
BUG/MINOR: mux-quic/h3: properly handle too low peer fctl initial stream
BUG/MEDIUM: h3: do not overwrite interim with final response
BUG/MINOR: h3: properly realloc buffer after interim response encoding
BUG/MINOR: h3: ensure that invalid status code are not encoded (FE side)
MINOR: qmux: change API for snd_buf FIN transmission
BUG/MEDIUM: h3: handle interim response properly on FE side
BUG/MINOR: hq-interop: fix FIN transmission
BUG/MINOR mux-quic: apply correctly timeout on output pending data
DOC: list missing global QUIC settings
BUG/MINOR: mux-h1: fix wrong lock label
BUG/MEDIUM: quic: reset padding when building GSO datagrams
BUG/MINOR: quic: do not emit probe data if CONNECTION_CLOSE requested
BUG/MAJOR: quic: fix INITIAL padding with probing packet only
BUG/MINOR: quic: don't coalesce probing and ACK packet of same type
MINOR: quic: centralize padding for HP sampling on packet building
BUG/MINOR: connection: rearrange union list members
BUG/MINOR: connection: remove extra session_unown_conn() on reverse
BUG/MINOR: server: decrement session idle_conns on del server
MINOR: doc: add missing statistics column
MINOR: doc: add missing statistics column
BUG/MAJOR: mux-quic: fix crash on reload during emission
BUG/MINOR: quic: fix room check if padding requested
BUG/MINOR: quic: fix padding issue on INITIAL retransmit
BUG/MEDIUM: conn: fix UAF on connection after reversal on edge
BUG/MINOR: connection: streamline conn detach from lists
CLEANUP: quic: fix typo in quic_tx trace
OPTIM: check: do not delay MUX for ALPN if SSL not active
BUG/MEDIUM: checks: fix ALPN inheritance from server
Aurelien DARRAGON (5):
BUG/MEDIUM: hlua_fcn: ensure systematic watcher cleanup for server list
iterator
BUG/MEDIUM: logs: fix sess_build_logline_orig() recursion with options
BUG/MINOR: hlua: take default-path into account with lua-load-per-thread
BUG/MINOR: logs: fix log-steps extra log origins selection
BUG/MINOR: log: fix potential memory leak upon error in
add_to_logformat_list()
Christopher Faulet (39):
DOC: config: Fix a typo in 2.7 (Name format for maps and ACLs)
BUG/MEDIUM: check: Requeue healthchecks on I/O events to handle check
timeout
BUG/MINOR: mux-spop: Fix null-pointer deref on SPOP stream allocation
failure
BUG/MINIR: h1: Fix doc of 'accept-unsafe-...-request' about URI parsing
BUG/MINOR: http-ana: Properly handle keep-query redirect option if no QS
BUG/MEDIUM: cli: Don't consume data if outbuf is full or not available
MINOR: cli: handle EOS/ERROR first
BUG/MEDIUM: check: Set SOCKERR by default when a connection error is
reported
BUG/MINOR: stream: Avoid recursive evaluation for unique-id based on
itself
BUG/MINOR: log: Be able to use %ID alias at anytime of the stream's
evaluation
BUG/MEDIUM: hlua: Forbid any L6/L7 sample fetche functions from lua
services
BUG/MEDIUM: mux-h2: Properly handle connection error during preface
sending
BUG/MINOR: hlua: Skip headers when a receive is performed on an HTTP
applet
BUG/MEDIUM: hlua: Report to SC when data were consumed on a lua socket
BUG/MEDIUM: hlua: Report to SC when output data are blocked on a lua
socket
BUG/MEDIUM: dns: Reset reconnect tempo when connection is finally
established
BUG/MEDIUM: http-client: Don't wake http-client applet if nothing was
xferred
BUG/MEDIUM: http-client: Properly inc input data when HTX blocks are
xferred
BUG/MEDIUM: http-client: Ask for more room when request data cannot be
xferred
BUG/MINOR: http-client: Ignore 1XX interim responses in non-HTX mode
BUG/MINOR: http-client: Reject any 101-switching-protocols response
BUG/MEDIUM: http-client: Drain the request if an early response is
received
BUG/MEDIUM: http-client: Notify applet has more data to deliver until the
EOM
BUG/MINOR: applet: Don't trigger BUG_ON if the tid is not on appctx init
BUG/MEDIUM: http-client: Test HTX_FL_EOM flag before commiting the HTX
buffer
BUG/MINOR: spoe: Properly detect and skip empty NOTIFY frames
BUG/MEDIUM: mux-spop: Reject connection attempts from a non-spop frontend
BUG/MEDIUM: spoe: Improve error detection in SPOE applet on client abort
BUG/MEDIUM: stconn: Fix conditions to know an applet can get data from
stream
BUG/MEDIUM: Remove sync sends from streams to applets
REG-TESTS: map_redirect: Don't use hdr_dom in ACLs with "-m end" matching
method
BUG/MEDIUM: server: Duplicate healthcheck's alpn inherited from default
server
BUG/MAJOR: stream: Remove READ/WRITE events on channels after analysers
eval
BUG/MAJOR: stream: Force channel analysis on successful synchronous send
MINOR: server: Parse sni and pool-conn-name expressions in a dedicated
function
BUG/MEDIUM: server: Use sni as pool connection name for SSL server only
BUG/MINOR: server: Update healthcheck when server settings are changed
via CLI
BUG/MINOR: pattern: Properly flag virtual maps as using samples
BUG/MINOR: pattern: Fix pattern lookup for map with opt@ prefix
David Carlier (2):
BUILD/MEDIUM: deviceatlas: fix when installed in custom locations.
DOC: deviceatlas build clarifications
Frederic Lecaille (11):
BUG/MINOR: quic: Missing SSL session object freeing
BUG/MINOR: quic: wrong QUIC_FT_CONNECTION_CLOSE(0x1c) frame encoding
MINOR: quic: Useless TX buffer size reduction in closing state
BUG/MINOR: quic: Wrong source address use on FreeBSD
BUG/MINOR: quic: reorder fragmented RX CRYPTO frames by their offsets
MINOR: quic: remove ->offset qf_crypto struct field
BUG/MINOR: mux-quic: trace with non initialized qcc
CLEANUP: quic: remove a useless CRYPTO frame variable assignment
BUG/MEDIUM: quic: CRYPTO frame freeing without eb_delete()
BUG/MINOR: quic: ignore AGAIN ncbuf err when parsing CRYPTO frames
MINOR: quic: Add more information about RX packets
Lukas Tribus (2):
DOC: management: fix typo in commit f4f93c56
DOC: config: recommend single quoting passwords
Olivier Houchard (7):
BUG/MEDIUM: fd: Use the provided tgid in fd_insert() to get tgroup_info
BUG/MEDIUM: threads: Disable the workaround to load libgcc_s on macOS
BUG/MEDIUM: ssl: Fix 0rtt to the server
BUG/MEDIUM: ssl: fix build with AWS-LC
BUG/MEDIUM: h1: Allow reception if we have early data
BUG/MEDIUM: ssl: create the mux immediately on early data
BUG/MEDIUM: stick-tables: Don't let table_process_entry() handle refcnt
Remi Tricot-Le Breton (4):
BUG/MINOR: jwt: Copy input and parameters in dedicated buffers in
jwt_verify converter
DOC: Fix 'jwt_verify' converter doc
BUG/MINOR: init: Initialize random seed earlier in the init process
BUG/MINOR: ocsp: Crash when updating CA during ocsp updates
Valentine Krasnobaeva (9):
DOC: config: prefer-last-server: add notes for non-deterministic
algorithms
BUG/MINOR: tools: use my_unsetenv instead of unsetenv
BUG/MINOR: halog: exit with error when some output filters are set
simultaneosly
BUG/MINOR: stick-table: cap sticky counter idx with tune.nb_stk_ctr
instead of MAX_SESS_STKCTR
MEDIUM: dns: don't call connect to dest socket for AF_INET*
MINOR: dns: dns_connect_nameserver: fix fd leak at error path
MINOR: compiler: add __nonstring macro
BUG/MINOR: acl: set arg_list->kw to aclkw->kw string literal if aclkw is
found
BUG/MINOR: resolvers: always normalize FQDN from response
William Lallemand (13):
BUG/MEDIUM: ssl/clienthello: ECDSA with ssl-max-ver TLSv1.2 and no ECDSA
ciphers
DOC: configuration: add details on prefer-client-ciphers
MINOR: ssl: check TLS1.3 ciphersuites again in clienthello with recent
AWS-LC
BUG/MINOR: httpclient: wrongly named httpproxy flag
DOC: management: clarify usage of -V with -c
MEDIUM: ssl/cli: relax crt insertion in crt-list of type directory
BUG/MEDIUM: mworker: more verbose error upon loading failure
BUG/MEDIUM: mworker: fix startup and reload on macOS
BUILD: mworker: fix ignoring return value of ‘read’
DOC: unreliable sockpair@ on macOS
DOC: configuration: confuse "strict-mode" with "zero-warning"
BUILD: halog: misleading indentation in halog.c
BUG/MEDIUM: ssl: ca-file directory mode must read every certificates of a
file
Willy Tarreau (20):
MINOR: http: add a function to validate characters of :authority
BUG/MEDIUM: h2/h3: reject some forbidden chars in :authority before
reassembly
BUG/MEDIUM: h1/h2/h3: reject forbidden chars in the Host header field
BUILD: tools: properly define ha_dump_backtrace() to avoid a build warning
SCRIPTS: drop the HTML generation from announce-release
BUILD: dev/phash: remove the accidentally committed a.out file
BUG/MINOR: listener: really assign distinct IDs to shards
BUILD: compat: provide relaxed versions of the MIN/MAX macros
BUILD: compat: always set _POSIX_VERSION to ease comparisons
BUG/MINOR: haproxy: be sure not to quit too early on soft stop
BUILD: acl: silence a possible null deref warning in parse_acl_expr()
REGTESTS: explicitly use "balance roundrobin" where RR is needed
BUILD: trace: silence a bogus build warning at -Og
BUG/MINOR: cpu_topo: work around a small bug in musl's CPU_ISSET()
BUG/MINOR: activity: fix reporting of task latency
BUG/MEDIUM: ring: invert the length check to avoid an int overflow
OPTIM: sink: reduce contention on sink_announce_dropped()
MINOR: ssl: add the ssl_bc_sni sample fetch function to retrieve backend
SNI
DOC: config: clarify some known limitations of the json_query() converter
BUG/CRITICAL: mjson: fix possible DoS when parsing numbers
zhanhb (2):
BUG/MINOR: h2: forbid 'Z' as well in header field names checks
BUG/MINOR: h3: forbid 'Z' as well in header field names checks
--
Christopher Faulet