Hi, HAProxy 3.2.5 was released on 2025/09/22. It added 93 new commits after version 3.2.4.
This release, as usual, fixed several bugs at various places. Some fixes were not shipped in this release and will be backported just after to avoid, as far as possible, risk of regressions. Among other fixes, several improvements on stick-tables and fixes on resolvers were delayed. The first ones because the changes are far to be trivial and deserve to be more tested. The second ones because, in the past, every-time we have touched to the resolvers, regressions were introduced ! So we hope to emit a clean and safe release this way. All delayed fixes will be shipped with the 3.2.6 and can be tested till then. Here is the list of most significant ones: 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. 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. So the fix will be slowly backported to older stable versions because the risk of regression is high. On the H2 multiplexer, new cases of blocked H2 connection because of unparsed incoming data were found. This could even lead to wakeup loops in some cases. They were all fixed. An ABORT_NOW() directive used during debugging of idle-ping was forgotten in the code. It was removed to avoid crashes, especially when idle-ping was mixed with shorter http-request/http-keep-alive values. It was possible to freeze the CLI socket when a large commands pipeline was parsed, larger enough to fully fill the input buffer. Consumed data were not properly acknowledged and the input buffer still appeared to be full. Worse, a spinning loop could be encountered if a client shutdown was detected in that state. This was fixed by properly updating the input buffer state when consuming commands. "check-reuse-pool" server directive could be ineffective when server relied on SSL because healthchecks inherited in a wrong way from server settings. In addition, the connection reuse implied by this option was not effective for regular HTTP server (i.e. not reversed-HTTP server) because the destination address was not considered as expected in the connection hash calculation. Now, it should be possible to reuse existing connection to perform healthchecks on regular HTTP servers. In addition, 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. Finally, 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. Handling of early data was improved to make it work as expected and be processed before end of the SSL handshake. 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 in haproxy 3.1. 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. On HTTP analysis, the yield mechanism on HTTP rulesets introduced in 3.2 was not properly handled for "stats http-request" rules. An interrupted evaluation was never resumed and the request would continue to be handled as if the evaluation was complete. This in fact revealed the same issue, there from a while, with all actions able to yield, as lua actions for instance. To fix the issue, handling of all rulesets was merged. 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. An infinite loop could be experienced when a pattern value was modified because of a wrong loop construction, a continue statement at the wrong place. 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. The way the "ssl-f-use" directive handled during the configuration parsing has changed to be less confusing. Instead of using it only on SSL bind lines without "crt" directive, it is now applied on every SSL bind lines. The task latency reported by "show tasks" command was not correctly computed. The CPU topology was not properly detected on musl 1.25 leading to ignore CPUs 32..63. Both issues were fixed. 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. Haproxy could stop too early on soft stop, without processing incoming traffic, which was visible with broken connections during reloads. To fix the issue, threads now ignore the the stopping condition until the signal queue is empty. Finally some issues were found in the stick-tables. It was possible to have orphan elements in a table because the loop responsible to remove expired entries could exit after a certain number of elements were expired, without requeuing the deleted elements. It was also possible to have orphan elements by leaving used entries without expiration date. However, this issue was trickier to trigger. Now we take care to requeue such entry with its expiration timer. It was possible to miss some wakeups of the task responsible to remove expired entries. This was fixed by reinforcing the test on the task's expiration date. And it was possible to trigger the watchdog from the peers when the expire task was running fast (i.e. running almost alone). In that case, it was super hard to grab the update lock and peers could spend too many time waiting for the lock, especially because the time it took to grab this lock was multiplied by the number of updates to perform. A try-lock is now used and we only accept one locking failure before exiting. Many thanks to Felipe and Ricardo for their invaluable help. Apart from these fixes, two sample fetch functions were backported. The first one is le2dec (little endian to decimal). It converts little-endian binary input samples into their decimal representations. The second one is base2 which converts binary input samples into their string representations. Thanks to Alexander Stephan and Maximilian Moehl. That's all for this release ! 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.2/src/ Git repository : https://git.haproxy.org/git/haproxy-3.2.git/ Git Web browsing : https://git.haproxy.org/?p=haproxy-3.2.git Changelog : https://www.haproxy.org/download/3.2/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 (7): MINOR: sample: Add le2dec (little endian to decimal) sample fetch 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 (22): BUG/MINOR: mux-h1: fix wrong lock label BUG/MEDIUM: mux-h2: fix crash on idle-ping due to unwanted ABORT_NOW 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/MINOR: check: ensure check-reuse is compatible with SSL BUG/MINOR: check: fix dst address when reusing a connection 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 (4): MINOR: http_ana: fix typo in http_res_get_intercept_rule BUG/MEDIUM: http_ana: handle yield for "stats http-request" evaluation BUG/MINOR: log: fix potential memory leak upon error in add_to_logformat_list() BUG/MEDIUM: http_ana: fix potential NULL deref in http_process_req_common() Christopher Faulet (16): BUG/MEDIUM: stconn: Fix conditions to know an applet can get data from stream BUG/MEDIUM: Remove sync sends from streams to applets BUG/MINOR: spoe: Properly detect and skip empty NOTIFY frames BUG/MEDIUM: cli: Report inbuf is no longer full when a line is consumed BUG/MEDIUM: mux-spop: Reject connection attempts from a non-spop frontend BUG/MEDIUM: spoe: Improve error detection in SPOE applet on client abort 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/MEDIUM: mux-h2: Reset MUX blocking flags when a send error is caught BUG/MEDIUM: mux-h2; Don't block reveives in H2_CS_ERROR and H2_CS_ERROR2 states BUG/MEDIUM: mux-h2: Restart reading when mbuf ring is no longer full BUG/MINOR: mux-h2: Remove H2_CF_DEM_DFULL flags when the demux buffer is reset BUG/MEDIUM: mux-h2: Report RST/error to app-layer stream during 0-copy fwding BUG/MEDIUM: mux-h2: Reinforce conditions to report an error to app-layer stream BUG/MAJOR: stream: Remove READ/WRITE events on channels after analysers eval BUG/MAJOR: stream: Force channel analysis on successful synchronous send Frederic Lecaille (9): MINOR: quic: implement qc_ssl_do_hanshake() BUG/MEDIUM: quic: listener connection stuck during handshakes (OpenSSL 3.5) 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 Maximilian Moehl (1): MINOR: sample: Add base2 converter Olivier Houchard (2): BUG/MEDIUM: h1: Allow reception if we have early data BUG/MEDIUM: ssl: create the mux immediately on early data Remi Tricot-Le Breton (3): BUG/MINOR: ssl: Potential NULL deref in trace macro BUG/MINOR: ssl: Fix potential NULL deref in trace callback BUG/MINOR: ocsp: Crash when updating CA during ocsp updates Valentine Krasnobaeva (4): MEDIUM: dns: don't call connect to dest socket for AF_INET* MINOR: dns: dns_connect_nameserver: fix fd leak at error path 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 (11): BUG/MEDIUM: mworker: more verbose error upon loading failure BUG/MEDIUM: ssl: apply ssl-f-use on every "ssl" bind MINOR: ssl: diagnostic warning when both 'default-crt' and 'strict-sni' are used DOC: configuration: clarify 'default-crt' and implicit default certificates 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" BUG/MINOR: acme: null pointer dereference upon allocation failure BUG/MEDIUM: jws: return size_t in JWS functions BUG/MINOR: ocsp: prototype inconsistency Willy Tarreau (14): 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() BUG/MEDIUM: stick-tables: don't leave the expire loop with elements deleted BUG/MINOR: stick-tables: never leave used entries without expiration BUG/MEDIUM: peers: don't fail twice to grab the update lock 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: stick-tables: don't loop on non-expirable entries BUG/MINOR: stick-table: make sure never to miss a process_table_expire update BUG/MEDIUM: ring: invert the length check to avoid an int overflow DEBUG: stick-tables: export stktable_add_pend_updates() for better reporting BUG/MEDIUM: pattern: fix possible infinite loops on deletion (try 2) -- Christopher Faulet

