Hi, HAProxy 3.4-dev8 was released on 2026/04/03. It added 159 new commits after version 3.4-dev7.
42 bugs were fixed in this release, nothing really important this time. The most visible changes this time include: - acme: when using the dns-01 challenge type, haproxy can now pre-check the propagation of the challenge update in the DNS via periodic TXT record probes. This can be enabled via the new "challenge-ready dns" directive in the acme section. This ensures we don't tell the ACME servers too early to check a challenge which might not yet have propagated. It's also possible to set it to "cli" to manually validate the propagation. - a preliminary implementation of the QMux protocol (formerly known as "quic over streams" or "quic over tcp", and currently defined here: https://www.ietf.org/archive/id/draft-opik-quic-qmux-01.html) was integrated into the QUIC mux. Both the draft and the implementation are early. This works both on the frontend and the backend, and are totally experimental (do not use this outside of the lab yet). The goal is to be able to transport HTTP/3 over TCP networks, which can be desirable on the backend as a more modern alternative to HTTP/2. It still has rough edges but the code reached a state where it could integrate well, and we hope this will help the standard make forward progress and benefit from real world feedback. This is currently enabled by specifying "proto qmux" on the "bind" or "server" lines. - small buffers: keeping small requests in larger buffers while the request is waiting in queue consumes memory for no reason. This is particularly visible on overloaded nodes which would possibly prefer to make a more careful usage of their memory. It is also the case for L7 retries, where the request is duplicated before being sent to the server. The new backend option "option use-small-buffers" allows haproxy to reallocate a small buffer instead of a standard one to preserve the request for the time it needs to, and the size is set via "tune.bufsize.small". It is expected that most setups will not notice any difference but that a few ones where this matters could notice a big difference in memory usage. - connections: the interactions between "proto", "alpn", and the protocol possibly placed in server addresses still had blind corners making it impossible for example to mix QUIC vs HTTP in checks vs prod traffic. The internals were revisited a bit to permit check to have a QUIC address and let the QUIC mux automatically be selected for such address classes. - new HTTP actions set-headers-bin, add-headers-bin and del-headers-bin permit to process a group of headers at once. The goal is to ease passing groups of headers from servers, filters or SPOA. It is also possible to use this to save a copy of existing headers and restore them later. A prefix is supported to filter only ones of interest. - dynamic backends: it was previously not possible to dynamically add backends that would depend on a defaults section using http-errors, this is possible now. - scheduler: some changes were made to avoid some latency degradations that could be observed under extreme loads that could result from attacks or recovering from a bad situation. The self-waking tasks are no longer penalized forever because this happens when yielding to preserve low latency. Tasklets that would be woken up from a best effort service task would be contaminated by that task and experience the same fate. And some mutually-waking tasks in the same class could keep the scheduler busy longer than needed and lower the bandwidth available to other tasks. The results vary a lot between workloads but significant latency improvements were measured, notably on the CLI which remains much more responsive even with 100000 tasks in the run queue. - health check sections: it is now possible to declare new "healthcheck" sections containing check rules that can be reused for different servers. And with the "healthcheck" server directive, a server can now use a predefined check method. This can simplify the deployment of complex checks, as well as permit to run distinct checks on distinct servers of the same backend (e.g. check active servers with a complex method, and backup ones with a simpler method). I'm noticing now that there's a typo in the doc, the server keyword says "healthchec" (without the 'k') but the correct one definitely is with the 'k' :-) - HTTP/2: some users running with very large (multi-MB) tune.bufsize would sometimes experience high latencies in HTTP/2 when parsing lots of small frames. It's now possible to limit the number of frames that will be processed in one call using "tune.h2.fe.max-frames-at-once" for the frontend, and "tune.h2.be.max-frames-at-once" for the backend. Moreover, the new "tune.h2.fe.max-rst-at-once" allows to yield more often when processing RST_STREAM frames. It proves extremely effective to just set this one to a low value (e.g. "1") to avoid CPU and latency spikes caused by RST_STREAM floods. Also important to note, glitches will now be counted for RST_STREAM frames received before the task had a chance to start running (strong suspicion of a flood). And a few less important updates: - tune.idle-pool.shared now also supports "full" to indicate that idle connections must be shared across all thread groups. This is not recommended at all but might make sense on low loads with many idle connections where it could reduce the number of sockets in use. This replaces directive tune.takeover-other-tg-connections that will be deprecated. Oops, I'm noticing that the doc and error messages mention "auto" instead of "full". - the haproxy version will no longer be displayed by default on the stats page, though it can still be enabled using "stats-show-version". - haterm now supports zero-copy and splicing. It should theoretically permit to fully use kTLS hardware acceleration now, this will need to be tested again ;-) - do-log action: it's not possible to specify the log profile to use via "profile <name>" on a do-log action. - new environment variables HAPROXY_KEYLOG_{FC,BC}_LOG_FMT contain the log format for SSL keylog files - some minor optmimizations, doc, cleanups, and CI updates So overall this is plenty of good stuff. I'd really like to get a bit more testing feedback now that efforts are mostly centered on fixing remaining issues. It's worth noting that we had one crash last week with 3.4-dev7 that was never reproduced, but unfortunately we didn't have the core, though certain issues that could possibly cause a crash were fixed since. As such I'm even more interested in feedback for dev8. 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.4/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.4/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 (39): MINOR: http_htx: use enum for arbitrary values in conf_errors MINOR: http_htx: rename fields in struct conf_errors MINOR: http_htx: split check/init of http_errors MINOR/OPTIM: http_htx: lookup once http_errors section on check/init MEDIUM: proxy: remove http-errors limitation for dynamic backends BUG/MINOR: http_htx: fix null deref in http-errors config check BUG/MINOR: quic: close conn on packet reception with incompatible frame DOC: configuration: mention QUIC server support MINOR: connection: add function to identify a QUIC connection MINOR: quic: refactor frame parsing MINOR: quic: refactor frame encoding BUG/MINOR: quic: fix documentation for transport params decoding MINOR: quic: split transport params decoding/check MINOR: quic: remove useless quic_tp_dec_err type MINOR: quic: define QMux transport parameters frame type MINOR: quic: implement QMux transport params frame parser/builder MINOR: mux-quic: move qcs stream member into tx inner struct MINOR: mux-quic: prepare Tx support for QMux MINOR: mux-quic: convert init/closure for QMux compatibility MINOR: mux-quic: protect qcc_io_process for QMux MINOR: mux-quic: prepare traces support for QMux MINOR: quic: abstract stream type in qf_stream frame MEDIUM: mux-quic: implement QMux receive MINOR: mux-quic: handle flow-control frame on qstream read MINOR: mux-quic: define Rx connection buffer for QMux MINOR: mux_quic: implement qstrm rx buffer realign MEDIUM: mux-quic: implement QMux send MINOR: mux-quic: implement qstream send callback MINOR: mux-quic: define Tx connection buffer for QMux MINOR: xprt_qstrm: define new xprt module for QMux protocol MINOR: xprt_qstrm: define callback for ALPN retrieval MINOR: xprt_qstrm: implement reception of transport parameters MINOR: xprt_qstrm: implement sending of transport parameters MEDIUM: ssl: load xprt_qstrm after handshake completion MINOR: mux-quic: use QMux transport parameters from qstrm xprt MAJOR: mux-quic: activate QMux for frontend side MAJOR: mux-quic: activate QMux on the backend side DEBUG: connection/flags: add QSTRM flags for the decoder BUG/MINOR: mux_quic: fix uninit for QMux emission Aurelien DARRAGON (3): MINOR: log: split do_log() in do_log() + do_log_ctx() MINOR: log: provide a way to override logger->profile from process_send_log_ctx MINOR: log: support optional 'profile <log_profile_name>' argument to do-log action Christopher Faulet (51): MINOR: buffers: Move small buffers management from quic to dynbuf part MINOR: dynbuf: Add helper functions to alloc large and small buffers MINOR: quic: Use b_alloc_small() to allocate a small buffer MINOR: config: Relax tests on the configured size of small buffers MINOR: config: Report the warning when invalid large buffer size is set MEDIUM: htx: Add htx_xfer function to replace htx_xfer_blks MINOR: htx: Add helper functions to xfer a message to smaller or larger one MINOR: http-ana: Use HTX API to move to a large buffer MEDIUM: chunk: Add support for small chunks MEDIUM: stream: Try to use a small buffer for HTTP request on queuing MEDIUM: stream: Try to use small buffer when TCP stream is queued MEDIUM: stconn: Use a small buffer if possible for L7 retries MEDIUM: tree-wide: Rely on htx_xfer() instead of htx_xfer_blks() Revert "BUG/MEDIUM: mux-h2: make sure to always report pending errors to the stream" MEDIUM: mux-h2: Stop dealing with HTX flags transfer in h2_rcv_buf() MEDIUM: tcpcheck: Use small buffer if possible for healthchecks MINOR: proxy: Review options flags used to configure healthchecks DOC: config: Fix alphabetical ordering of proxy options DOC: config: Fix alphabetical ordering of external-check directives MINOR: proxy: Add use-small-buffers option to set where to use small buffers DOC: config: Add missing 'status-code' param for 'http-check expect' directive DOC: config: Reorder params for 'tcp-check expect' directive BUG/MINOR: config: Warn only if warnif_cond_conflicts report a conflict BUG/MINOR: config: Properly test warnif_misplaced_* return values BUG/MINOR: http-ana: Only consider client abort for abortonclose BUG/MEDIUM: htx: Fix htx_xfer() to consume more data than expected CLEANUP: stconn: Remove usless sc_new_from_haterm() declaration BUG/MINOR: stconn: Always declare the SC created from healthchecks as a back SC BUG/MINOR: http_act: Properly handle decoding errors in *-headers-bin actions BUG/MINOR: http_act: Make set/add-headers-bin compatible with ACL conditions MINOR: action: Add a sample expression field in arguments used by HTTP actions MEDIUM: http_act: Rework *-headers-bin actions BUG/MINOR: tcpcheck: Remove unexpected flag on tcpcheck rules for httchck option MEDIUM: tcpcheck: Refactor how tcp-check rulesets are stored MINOR: tcpcheck: Deal with disable-on-404 and send-state in the tcp-check itself BUG/MINOR: tcpcheck: Don't enable http_needed when parsing HTTP samples MINOR: tcpcheck: Use tcpcheck flags to know a healthcheck uses SSL connections BUG/MINOR: tcpcheck: Use tcpcheck context for expressions parsing CLEANUP: tcpcheck: Don't needlessly expose proxy_parse_tcpcheck() MINOR: tcpcheck: Add a function to stringify the healthcheck type MEDIUM: tcpcheck: Split parsing functions to prepare healthcheck sections parsing MEDIUM: tcpcheck: Add parsing support for healthcheck sections MINOR: tcpcheck: Extract tcpheck ruleset post-config in a dedicated function MEDIUM: tcpcheck/server: Add healthcheck server keyword REGTESTS: tcpcheck: Add a script to check healthcheck section MINOR: hasterm: Change hstream_add_data() to prepare zero-copy data forwarding MEDIUM: haterm: Add support for 0-copy data forwading and option to disable it MEDIUM: haterm: Prepare support for splicing by initializing a master pipe MEDIUM: haterm: Add support for splicing and option to disable it MINOR: haterm: Handle boolean request options as flags MINOR: haterm: Add an request option to disable splicing Cody Ohlsen (1): BUG/MEDIUM: mux-h1: Don't set MSG_MORE on bodyless responses forwarded to client David Carlier (1): BUG/MEDIUM: acme: fix multiple resource leaks in acme_x509_req() Egor Shestakov (1): BUG/MINOR: sock: adjust accept() error messages for ENFILE and ENOMEM Emeric Brun (1): BUG/MINOR: net_helper: fix length controls on ip.fp tcp options parsing Frederic Lecaille (1): BUG/MINOR: qpack: fix 62-bit overflow and 1-byte OOB reads in decoding Ilia Shipitsin (3): CI: github: fix tag listing by implementing proper API pagination CLEANUP: fix typos and spelling in comments and documentation CLEANUP: net_helper: fix typo in comment Mia Kanashi (1): BUG/MEDIUM: acme: skip doing challenge if it is already valid Nenad Merdanovic (1): MEDIUM: Add set-headers-bin, add-headers-bin and del-headers-bin actions Olivier Houchard (9): BUG/MEDIUM: check: Don't reuse the server xprt if we should not MINOR: checks: Store the protocol to be used in struct check MINOR: protocols: Add a new proto_is_quic() function MEDIUM: connections: Enforce mux protocol requirements MEDIUM: server: remove a useless memset() in srv_update_check_addr_port. MINOR: connections: Enhance tune.idle-pool.shared MEDIUM: stats: Hide the version by default and add stats-showversion MINOR: backends: Don't update last_sess if it did not change MINOR: servers: Don't update last_sess if it did not change William Lallemand (32): BUG/MINOR: acme: leak of ext_san upon insertion error BUG/MINOR: acme: wrong error when checking for duplicate section BUG/MINOR: acme/cli: wrong argument check in 'acme renew' BUG/MINOR: acme: NULL check on my_strndup() BUG/MINOR: acme: free() DER buffer on a2base64url error path BUG/MINOR: acme: replace atol with len-bounded __strl2uic() for retry-after BUG/MINOR: acme/cli: fix argument check and error in 'acme challenge_ready' BUILD: tools: potential null pointer dereference in dl_collect_libs_cb BUG/MINOR: ech: permission checks on the CLI BUG/MINOR: acme: permission checks on the CLI BUG/MINOR: acme: fix task allocation leaked upon error MINOR: resolvers: basic TXT record implementation MINOR: acme: store the TXT record in auth->token MEDIUM: acme: add dns-01 DNS propagation pre-check MEDIUM: acme: new 'challenge-ready' option DOC: configuration: document challenge-ready and dns-delay options for ACME BUG/MEDIUM: ssl/cli: tls-keys commands warn when accessed without admin level BUG/MEDIUM: ssl/ocsp: ocsp commands warn when accessed without admin level BUG/MEDIUM: map/cli: map/acl commands warn when accessed without admin level BUG/MEDIUM: ssl/cli: tls-keys commands are missing permission checks BUG/MEDIUM: ssl/ocsp: ocsp commands are missing permission checks BUG/MEDIUM: map/cli: CLI commands lack admin permission checks MINOR: ssl/log: add keylog format variables and env vars DOC: configuration: update tune.ssl.keylog URL to IETF draft MINOR: acme: add 'dns-timeout' keyword for dns-01 challenge MINOR: acme: set the default dns-delay to 30s MINOR: acme: split the CLI wait from the resolve wait MEDIUM: acme: initialize the dns timer starting from the first DNS request MINOR: acme: remove remaining CLI wait in ACME_RSLV_TRIGGER MEDIUM: acme: split the initial delay from the retry DNS delay MINOR: ssl: add the ssl_fc_crtname sample fetch BUG/MINOR: ssl: fix memory leak in ssl_fc_crtname by using SSL_CTX ex_data index Willy Tarreau (15): MEDIUM: sched: do not run a same task multiple times in series MINOR: sched: do not requeue a tasklet into the current queue MINOR: sched: do not punish self-waking tasklets anymore MEDIUM: sched: do not punish self-waking tasklets if TASK_WOKEN_ANY MEDIUM: sched: change scheduler budgets to lower TL_BULK MINOR: mux-h2: assign a limited frames processing budget BUILD: sched: fix leftover of debugging test in single-run changes MINOR: stconn: flag the stream endpoint descriptor when the app has started MINOR: mux-h2: report glitches on early RST_STREAM BUILD: net_helper: fix unterminated comment that broke the build SCRIPTS: git-show-backports: list new commits and how to review them with -L BUG/MINOR: cfgcond: properly set the error pointer on evaluation error BUG/MINOR: cfgcond: always set the error string on openssl_version checks BUG/MINOR: cfgcond: always set the error string on awslc_api checks BUG/MINOR: cfgcond: fail cleanly on missing argument for "feature" ---

