Hi, HAProxy 3.0.13 was released on 2025/12/17. It added 79 new commits after version 3.0.12.
This release covers the same range as the last two 3.1 releases. The list below was extracted from corresponding announces: - A missed initialization in QUIC could trigger a BUG_ON() hence provoke a crash in qc_rcv_buf(). - The way certain QUIC stacks recently started to send their crypto frames leaving a single byte hole between them was fundamentally incompatible with our storage model which requires at least 8 bytes holes. As such, some of them would experience random connection failures due to dropped frames. This required to rework that storage part (the "ncbuf" stuff) to support an alternate byte-addressed area that is compatible with this behavior that we initially considered as irrelevant and only likely used by attackers. This new work has been extensively tested in production where the issue was first reported, and given that there were some reports of recent Firefox versions triggering the issue, we considered that we should not wait to backport it. Thanks Annika for your wonderful help BTW! - We've got a report of accidental breakage in 3.0 of the hash algorithms involved in consistent hashing, that prevents some users from migrating from pre-3.0 to 3.0+ by causing too heavy a cache redistribution. The problem is that fixing it will also cause some redistribution for those running on affected versions. The overall consensus was that those not noticing the issue will not be impacted by the fix and those impacted by it have not upgraded because of it, so better fix it in any case. In order to know if you're subject to this problem, look for "hash-type consistent" in your config, and if present, then check if there is a "hash-key" setting. If the first one is present without the second one or with "hash-key id", you may notice a drop in cache hit ratio during the upgrade. If the cache hit ratio is already small (e.g. small storage), it may be better to upgrade all LB nodes at once. If the cache hit ratio is very high (large storage), it might be better to first upgrade one LB node to pre-heat the caches with the redistributed objects, then upgrade the other ones. But based on what was observed since then, it should pass smoothly at most if not all places. - 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. On some rare occasions, stick-table keys of type strings could sometimes be incorrectly indexed with some extra bytes past the final zero and appear as duplicates, causing entries to get mixed. This is one of the longest living bugs we've had, it's been there since the feature was implemented in 1.4-dev7 almost 16 years ago! - On the cli, sending many requests (e.g. "add map") would send one LF character at a time and would make socat's CPU usage quickly reach 100% and increase the update time. - We've got some reports of segfaults at boot with GCC 15 and tree vectorization being applied to unaligned data at -O3, only for certain very specific targets (westmere and nehalem only). An extra build option to calm down that optimization was added that got rid of the issue, and greeted us with the pleasant surprise of improving the -O3 request rate by about 5%. All optimizations are not always as effective as planned. - 1xx responses in HTTP/3 were not always properly encoded if they would appear in the same response packet as the final response, and they would generally cause a parsing error on the client, which will abort the connection; 1xx sent along the final response are really not common right now and mostly happen in testing, but some applications could trigger them more than others. - A slow memory leak of SSL captures has been noticed over the last two years on haproxy.org, making us believe that it was in the SSL lib, because the counters we placed around it showed more calls to the init() callback than the release() one. We were actually wrong and discovered that in TLS 1.3 there can be two consecutive Client Hello messages on a connection and that this caused the capture area to be allocated twice and only the last one was freed. At least it explained everything, and this was fixed (and confirms to no longer leak). - A ring that would fail to connect to one of its servers could remain stuck forever if unlucky and it happens at a precise ms within the 20 first seconds of boot (then every 49.7 days). - A case of rare crashes was addressed when idle connections are purged, woken up and reused at the same time. Most users will never notice it, we triggered it around 500k req/s on 128 threads... - Updating a CA from the CLI could occasionally cause a crash due to objects being still referenced. - Default HTTP 405, 431 and 501 error files had an incorrect content length that would probably cause the front connections to be closed after the response. - 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 connection, 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. 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. 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 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, , 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 master process in 3.0 and lower. - 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. - 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, small fixes here and there and doc updates. 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.0/src/ Git repository : https://git.haproxy.org/git/haproxy-3.0.git/ Git Web browsing : https://git.haproxy.org/?p=haproxy-3.0.git Changelog : https://www.haproxy.org/download/3.0/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 (23): MINOR: quic: restore QUIC_HP_SAMPLE_LEN constant BUG/MEDIUM: h3: do not overwrite interim with final response 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: quic: don't coalesce probing and ACK packet of same type BUG/MINOR mux-quic: apply correctly timeout on output pending data BUG/MINOR: quic: check applet_putchk() for 'show quic' first line BUG/MEDIUM: h3: properly encode response after interim one in same buf MINOR: ncbuf: extract common types MINOR: ncbmbuf: define new ncbmbuf type MINOR: ncbmbuf: implement add MINOR: ncbmbuf: implement iterator bitmap utilities functions MINOR: ncbmbuf: implement ncbmb_data() MINOR: ncbmbuf: implement advance operation MINOR: ncbmbuf: add tests as standalone mode BUG/MAJOR: quic: use ncbmbuf for CRYPTO handling BUG/MEDIUM: connection: do not reinsert a purgeable conn in idle list BUG/MINOR: quic: close connection on CID alloc failure MINOR: mux-quic: refactor wait-for-handshake support 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 Aurelien DARRAGON (3): MINOR: sink: Remove useless test on SE_FL_SHR/SHW flags BUG/MINOR: sink: retry attempt for sft server may never occur BUG/MINOR: cfgparse-listen: update err_code for fatal error on proxy directive Christopher Faulet (13): BUG/MINOr: hlua: Fix receive from HTTP applet by properly accounting data BUG/MEDIUM: apppet: Improve spinning loop detection with the new API BUG/MEDIUM: applet: Improve again spinning loops detection with the new API 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() 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 BUG/MINOR: quic: SSL counters not handled Frederic Lecaille (4): BUG/MINOR: quic: too short PADDING frame for too short packets BUG/MAJOR: quic: uninitialized quic_conn_closed struct members MINOR: quic: Add useful debugging traces in qc_idle_timer_do_rearm() BUG/MINOR: quic: do not set first the default QUIC curves Huangbin Zhan (1): MINOR: http: fix 405,431,501 default errorfile Lukas Tribus (1): DOC: http: document 413 response code Olivier Houchard (4): BUG/MEDIUM: stick-tables: Don't forget to dec count on failure. 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 (5): BUG/MINOR: ssl: Free global_ssl structure contents during deinit BUG/MINOR: ssl: Free key_base from global_ssl structure during deinit BUG/MEDIUM: ssl: Crash because of dangling ckch_store reference in a ckch instance BUG/MINOR: init: Do not close previously created fd in stdio_quiet BUG/MINOR: jwt: Missing "case" in switch statement William Lallemand (8): MINOR: ssl: diagnostic warning when both 'default-crt' and 'strict-sni' are used BUILD: ssl: can't build when using -DLISTEN_DEFAULT_CIPHERS BUG/MEDIUM: mworker/listener: ambiguous use of RX_F_INHERITED with shards BUG/MINOR: ssl: returns when SSL_CTX_new failed during init DOC: configuration: add missing ssllib_name_startswith() DOC: configuration: add missing openssl_version predicates BUG/MINOR: ssl: remove dead code in ssl_sock_from_buf() MINOR: ssl: change visibility of ssl_stats_module Willy Tarreau (17): BUG/MEDIUM: ssl: take care of second client hello BUG/MINOR: ssl: always clear the remains of the first hello for the second one BUILD: makefile: disable tail calls optimizations with memory profiling BUG/MAJOR: lb-chash: fix key calculation when using default hash-key id BUG/MEDIUM: build: limit excessive and counter-productive gcc-15 vectorization BUG/MINOR: stick-tables: properly index string-type keys MINOR: applet: do not put SE_FL_WANT_ROOM on rcv_buf() if the channel is empty MINOR: cli: create cli_raw_rcv_buf() from the generic applet_raw_rcv_buf() BUG/MEDIUM: cli: do not return ACKs one char at a time DOC: config: slightly clarify the ssl_fc_has_early() behavior BUG/MEDIUM: mux-h2: make sure not to move a dead connection to idle 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 -- Christopher Faulet

