Hi, HAProxy 3.3-dev13 was released on 2025/11/14. It added 58 new commits after version 3.3-dev12.
This week I saw a few concerning bugs that started to made be doubt about our ability to deliver a quality release by the end of the month, but they were all found under stress conditions and all quickly addressed. Thus after all I'm realizing that instead it's rather pretty good news if we need to shake everything quite a bit to still observe bugs. Among the fixes, QUIC backend checks, session reuse and version negotiation were fixed, stick-tables failed attempts at locking an entry now properly report the failure and will no longer leave incorrect entry counts, the /dev/null FD was leaking in the master, the shm-stats-file was broken for the last 3 or 4 versions and is now fixed again, an issue that could make the HTTP/1 mux crash on certain H2 upgrades was also fixed, and the previous fix for the NULL mux was reverted and a different approach was taken as it would sometimes make the connection counters drift and break the CLI's "delete server". Some of the pending features that were not merged last week and that are not on the general paths were finally merged, essentially in the QUIC and ACME areas. The main visible changes in this release are the following: - QUIC backend 0-RTT support is now enabled when "allow-0rtt" is set on the server. This allows QUIC backends to resume encrypted sessions using previously negotiated parameters, reducing latency for subsequent connections. It works only with quictls and aws-lc as TLS stacks, and relies on proper session reuse including ALPN and transport parameters. At this point, backend QUIC is fairly complete and helps a lot in testing the frontend end by chaining two layers. I think the only remaining limitation is the impossibility to share a same idle connection between multiple threads for now. - QUIC backend now properly handles NEW_TOKEN frames, allowing HAProxy to store and reuse tokens from upstream servers for faster reconnections. This complements 0-RTT support and improves session continuity in distributed environments. - A long-standing issue affecting QUIC connection stability has been resolved: CID (Connection ID) collisions are now properly detected and handled. Previously, duplicate CIDs could slip through due to missing checks during connection setup or post-handshake operations, leading to rejected packets or even crashes. The fix ensures that when a collision occurs, the connection is either safely released or retried, preventing silent failures and improving reliability under high concurrency. This is scheduled for backporting. - The ACME scheduler was reworked to use a scalable ebmbtree with read-write locks instead of a linear list. This was done in anticipation of large setups with many certificates where we'd rather not run over long lists of hundreds of thousands of certs for each lookup. - Connection reuse in health checks is now properly restricted to HTTP-based check types, and a new diagnostic warning alerts users if "check-reuse-pool" is used with incompatible check types. - On the configuration side, new predicates have been added to help users conditionally configure TLS stacks: "awslc_api_atleast()" and "awslc_api_before()" allow fine-grained control based on AWS-LC API version, while "ssllib_name_startswith()" gives better matching for library-specific conditions. Some code cleanups continued, e.g. in the QUIC CID allocation logic, and traces were added there. We've also started to extend DEBUG_STRESS which now supports placing extra checks that are not welcome for production use (for performance reasons) but that sometimes allow to significantly speed up the detection of certain classes of bugs, e.g. by detecting a proof of the conditions that trigger the bug instead of the bug itself. For now this is extremely light but the goal is to extend this, because we had the patches available to detect the issue with the NULL mux fix, but they couldn't be integrated into normal code thus were not regularly tested. Here by merging the minimal infrastructure to add more tests later, it opens some room for backporting extra tests later. Regarding remaining issues, we're still deploying and stressing this version, and we'll look for an issue which was triggered by ACME which would apparently keep the previous process from stopping during reloads. It *might* have been related to some of the connection counters above, but not very likely, so more tests will help us figure that out. If any user sees 3.3-dev13 keep an old process running when using ACME, please try to report the usual info such as "show fd", "show sess all" etc. And please don't forget to test, really. 13 is not a bad number, here it's even way better than 12 ;-) 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.3/src/ Git repository : https://git.haproxy.org/git/haproxy.git/ Git Web browsing : https://git.haproxy.org/?p=haproxy.git Changelog : https://www.haproxy.org/download/3.3/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 Willy --- Complete changelog : Amaury Denoyelle (16): BUG/MINOR: quic: close connection on CID alloc failure 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 MINOR: quic: extend traces on CID allocation MEDIUM/OPTIM: quic: alloc quic_conn after CID collision check BUG/MINOR: do not account backend connections into maxconn MINOR: check: delay MUX init when SSL ALPN is used MINOR: cfgdiag: adjust diag on servers BUG/MINOR: check: only try connection reuse for http-check rulesets BUG/MINOR: check: fix reuse-pool if MUX inherited from server MINOR: check: clarify check-reuse-pool interaction with reuse policy MINOR: check: use auto SNI for QUIC checks MINOR: check: ensure QUIC checks configuration coherency Revert "BUG/MEDIUM: connections: permit to permanently remove an idle conn" BUG/MEDIUM: connection: do not reinsert a purgeable conn in idle list Aurelien DARRAGON (2): MINOR: stats-proxy: ensure future-proof FN_AGE manipulation in me_generate_field() BUG/MEDIUM: stats-file: fix shm-stats-file preload not working anymore Christopher Faulet (3): BUG/MEDIUM: stick-tables: Always return the good stksess from stktable_set_entry BUG/MINOR: stick-tables: Fix return value for __stksess_kill() CLEANUP: stick-tables: Don't needlessly compute shard number in stksess_free() Damien Claisse (1): MINOR: ssl/sample: expose ssl_*c_curve for AWS-LC Frederic Lecaille (19): BUG/MEDIUM: quic-be: do not launch the connection migration process MINOR: quic-be: Parse the NEW_TOKEN frame MEDIUM: quic-be: Parse, store and reuse tokens provided by NEW_TOKEN MINOR: quic-be: helper functions to save/restore transport params (0-RTT) MINOR: quic-be: helper quic_reuse_srv_params() function to reuse server params (0-RTT) MINOR: quic-be: Save the backend 0-RTT parameters MEDIUM: quic-be: modify ssl_sock_srv_try_reuse_sess() to reuse backend sessions (0-RTT) MINOR: quic-be: allow the preparation of 0-RTT packets MINOR: quic-be: Send post handshake frames from list of frames (0-RTT) MEDIUM: quic-be: qc_send_mux() adaptation for 0-RTT MINOR: quic-be: discard the 0-RTT keys MEDIUM: quic-be: enable the use of 0-RTT MINOR: quic-be: validate the 0-RTT transport parameters MINOR: quic-be: do not create the mux after handshake completion (for 0-RTT) MINOR: quic-be: avoid a useless I/O callback wakeup for 0-RTT sessions BUG/MINOR: quic-be: missing version negotiation CLEANUP: quic: Missing succesful SSL handshake backend trace (OpenSSL 3.5) BUG/MINOR: quic-be: backend SSL session reuse fix (OpenSSL 3.5) REGTEST: quic: quic/ssl_reuse.vtc supports OpenSSL 3.5 QUIC API Olivier Houchard (2): MINOR: h1: h1_release() should return if it destroyed the connection BUG/MEDIUM: h1: prevent a crash on HTTP/2 upgrade Remi Tricot-Le Breton (1): BUG/MEDIUM: init: 'devnullfd' not properly closed for master William Lallemand (8): BUG/MINOR: acme: more explicit error when BIO_new_file() BUG/MEDIUM: acme: move from mt_list to a rwlock + ebmbtree BUG/MINOR: acme: can't override the default resolver DOC: configuration: add missing ssllib_name_startswith() DOC: configuration: add missing openssl_version predicates MINOR: cfgcond: add "awslc_api_atleast" and "awslc_api_before" REGTESTS: ssl: activate ssl_curve_name.vtc for AWS-LC BUILD: ech: fix clang warnings Willy Tarreau (6): BUG/MEDIUM: config: for word expansion, empty or non-existing are the same CLEANUP: peers: remove an unneeded null check DEBUG: extend DEBUG_STRESS to ease testing and turn on extra checks DEBUG: add BUG_ON_STRESS(): a BUG_ON() implemented only when DEBUG_STRESS > 0 DEBUG: servers: add a few checks for stress-testing idle conns BUG/MINOR: check: fix QUIC check test when QUIC disabled ---

