Hi, HAProxy 3.1.11 was released on 2025/12/17. It added 54 new commits after version 3.1.10.
This release, as usual, fixed several bugs at various places : - The fix in 3.1.10 for the rare race condition that could occasionally cause a crash when an idle connection was ending at the exact same moment it was about to be purged didn't work well. It indeed plugged the race, but it broke connection accounting (it's in fact what caused the strange negative connection count I said I observed last time), because the flags that were being relied on are also used to update counters. This fix was reverted and a new, more involved one was made based on list membership, which looks better, and that this time we couldn't break. - In QUIC, collisions on CID generation were fixed to unsure a generated CID is not a duplicate value. Otherwise, at best, client packets would be rejected by haproxy, most probably with a STATELESS_RESET. At worst, crashes might be experienced. This is issue is pretty rare, but it can only be observed if running with a high number of concurrent connections in parallel. In addition, HyStart++ algorithm for QUIC connections is now disabled for congestion control algorithms not supporting it. It caused crashes when when it was enabled with BBR for instance. - An issue was fixed about stick-tables. The refcount of an entry can become inconsistent and prevent the entry from ever expiring if a local and remote update happen at the exact same time and the local entry is created at the moment the peers code releases the lock. - A crash that could occur after HTTP/2 upgrades from HTTP/1.1 has been resolved. The issue stemmed from the mux not being able to report that it had only released its structure and not the whole conenction, causing the SSL tasklet to never be freed while being returned as running, thus causing an infinite loop. - A failure to allocate a new QUIC Connection ID during a RETIRE_CONNECTION_ID frame was silently ignored, potentially leaving the peer without valid IDs and causing connection failures. Now, such allocation errors are treated as fatal, closing the connection promptly, which is safer when memory pressure is high and prevents silent degradation of connectivity. Related to SSL 0-RTT, the header "Early-data: 1" is now added on requests handled by haproxy as QUIC 0-RTT if the handshake is not yet completed. This is helpful to inform servers that such request should be processed carefully. Finally, an internal change during stream notification mechanism is introduced which is transparent to most users, however if you ever encountered frozen transfers it could be a solution for this. - The ALPN handling for listeners was improved to better handle cases where the protocol is forced with the "proto" keyword, preventing connection errors in certain configurations (e.g. when "proto h1" is forced while the default ALPN was still "h2,http/1.1"). - The value of "tune.maxpollevents" could lead to an integer overflow when calculating the size to be allocated, resulting in a failure that would cause the poller to process no events at all (in practice the process is totally unresponsive). The value is now capped to 1 million, which is 4000 times higher than the default (250) and already does not make much sense, it should not need to be touched again for the next century. - In master-worker mode, signal handling during startup and reload has been corrected. Previously, it was possible to trigger a reload while the configuration was still being parsed, leading to inconsistent states. Now, signals are properly blocked during parsing, ensuring atomicity and avoiding race conditions that could result in crashes or failed reloads. In addition, an ambiguity about a flag was fixed. It has no impact on 3.1 and upper thanks to the master-worker refactoring that has occurred in 3.1 but that led to a file descriptor leak for duplicated unix stats sockets in the matster process in 3.0 and lower. - A fix for applets that could trigger the spinning loop detection because of a mixup between read/send events and ability for an applet to receive and send. - A regression on the CLI about its new yield state, introduced in 3.1.10, was fixed. This new state was added to be able to send small response by batches to save CPU. - The tasks used to manage resolvers and the ones used to deal with communications with these resolvers are now single-threaded. These tasks were found to cause a lot of contention in the scheduler on high CPU count machines, for no added value. - On resolvers, the result of a "do-resolv" action was not cached, unlike it is stated in the documentation. The "hold valid" time is now respected. In addition, the round-robin selection on records in DNS answers was restored. It was accidentally broken during 2.5 development cycle. While it is an undocumented feature, some users relies on it, especially with the "do-resolv" action. - An old bug form 2012 was fixed about the HTTP TUNNEL handling that causing tunnelled streams closed by the server to be closed on both sides at once and logging an error. And the timer used for "wait-for-body" action was not properly reset, causing some trouble with some following actions, like "pause". - A typo in the "bc_settings_streams_limit" sample fetch function made it unavailable. This was fixed to accordingly to the name used in the configuration manual. The rest is pretty minor, essentially doc updates. The 3.2.10 and 3.3.1 should be emitted soon. We decided to delay these releases a bit to have the opportinity to fix an issue about idle connections, affecting the 3.3.0 and possibly the 3.2.9 too. 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 : Amaury Denoyelle (9): Revert "BUG/MEDIUM: connections: permit to permanently remove an idle conn" BUG/MEDIUM: connection: do not reinsert a purgeable conn in idle list BUG/MINOR: quic: close connection on CID alloc failure BUG/MEDIUM: mux-quic: ensure Early-data header is set BUG/MINOR: mux-quic: ensure close-spread-time is properly applied BUG/MEDIUM: mux-quic: adjust wakeup behavior MINOR: quic: adjust CID conn tree alloc in qc_new_conn() MINOR: quic: split CID alloc/generation function BUG/MEDIUM: quic: handle collision on CID generation Aurelien DARRAGON (1): BUG/MINOR: cfgparse-listen: update err_code for fatal error on proxy directive Christopher Faulet (22): BUG/MINOR: config: Limit "tune.maxpollevents" parameter to 1000000 BUG/MEDIUM: stick-tables: Always return the good stksess from stktable_set_entry BUG/MINOR: stick-tables: Fix return value for __stksess_kill() MINOR: muxes: Support an optional ALPN string when defining mux protocols MINOR: config: Do proto detection for listeners before checks about ALPN BUG/MEDIUM: config: Use the mux protocol ALPN by default for listeners if forced BUG/MEDIUM: resolvers: Properly cache do-resolv resolution BUG/MINOR: resolvers: Restore round-robin selection on records in DNS answers BUG/MEDIUM: resolvers: Test for empty tree when getting a record from DNS answer BUG/MEDIUM: resolvers: Make resolution owns its hostname_dn value BUG/MEDIUM: resolvers: Accept to create resolution without hostname BUG/MEDIUM: resolvers: Wake resolver task up whne unlinking a stream requester BUG/MEDIUM: h1-htx: Don't set HTX_FL_EOM flag on 1xx informational messages BUG/MINOR: http-ana: Reset analyse_exp date after 'wait-for-body' action BUG/MEDIUM: applet: Fix conditions to detect spinning loop with the new API BUG/MEDIUM: cli: State the cli have no more data to deliver if it yields BUG/MINOR: ssl: Don't allow to set NULL sni BUG/MEDIUM: http-ana: Don't close server connection on read0 in TUNNEL mode DOC: config: Fix description of the spop mode DOC: config: Improve spop mode documentation BUG/MEDIUM: mux-h2: Reset MUX blocking flags when a send error is caught BUG/MINOR: quic: SSL counters not handled Damien Claisse (1): BUG/MINOR: resolvers: ensure fair round robin iteration Frederic Lecaille (2): MINOR: quic: Add useful debugging traces in qc_idle_timer_do_rearm() BUG/MINOR: quic: do not set first the default QUIC curves Lukas Tribus (1): DOC: http: document 413 response code Olivier Houchard (3): MINOR: h1: h1_release() should return if it destroyed the connection BUG/MEDIUM: h1: prevent a crash on HTTP/2 upgrade BUG/MEDIUM: quic: Don't try to use hystart if not implemented Remi Tricot-Le Breton (1): BUG/MINOR: jwt: Missing "case" in switch statement William Lallemand (7): DOC: configuration: add missing ssllib_name_startswith() DOC: configuration: add missing openssl_version predicates BUG/MEDIUM: mworker: signals inconsistencies during startup and reload BUG/MINOR: mworker: wrong signals during startup BUG/MINOR: ssl: remove dead code in ssl_sock_from_buf() BUG/MEDIUM: mworker/listener: ambiguous use of RX_F_INHERITED with shards MINOR: ssl: change visibility of ssl_stats_module Willy Tarreau (7): BUG/MEDIUM: connection/ssl: also fix the ssl_sock_io_cb() regarding idle list MEDIUM: dns: bind the nameserver sockets to the initiating thread MEDIUM: resolvers: make the process_resolvers() task single-threaded BUG/MEDIUM: connection: fix "bc_settings_streams_limit" typo DOC: config: mention clearer that the cache's total-max-size is mandatory DOC: config: reorder the cache section's keywords BUG/MEDIUM: resolvers: break an infinite loop in resolv_get_ip_from_response() -- Christopher Faulet

