Hi, HAProxy 3.5-dev1 was released on 2026/06/25. It added 96 new commits after version 3.5-dev0.
It's been 3 weeks since 3.4 was released. So far, nothing dramatic to report, which is a good thing. There are still 37 fixes for various bugs whose severities range from minor to medium (though some could even be qualified of cosmetic). These ones will be described in the 3.4.1 announce that's coming^Walready done. There aren't that many new features yet, so it's a good moment to emit a new version so that those who were waiting for a -dev1 to start testing -dev again to help us have sometihng clean to start with. Aside usual bug fixes, here's what can be found in this version: - acme: events ACME_DEPLOY and ACME_NEWCERT are now available from Lua, allowing to write scripts that deal with cert updates, which is mostly useful with dns-01. An example of usage is provided in examples/lua/acme-gandi-livedns.lua. - Lua: the HTTP client can now perform multiple requests back-to-back from a single httpclient instance (it's no longer needed to instantiate a new client for each request). Also, the HTTP client returns status code 0 when an error is reported; in the past the error code used to be adjusted by the stream making the junction between the client and the connection itself, making it hard to know if a 503 was reported by haproxy or by the server for example. - scheduler: we completely got rid of the very old global wait queue in which unbound tasks were waiting. While the number of such tasks has been dramatically decreasing over the last versions, there were still some rare corner cases where a few of these would cause some occasional contention and overhead between many threads and waste CPU cycles, and even under exceptional circumstances cause a warning to be emitted. Now instead, waiting tasks are always in one thread's queue and temporarily belong to it, and when it's woken up, it runs either on that thread, or on another one if one if found to be significantly less loaded than the current one. In addition, in order to address the precise wakeup time requirements that were identified for haload's stats reporting, a new run queue was created for real-time tasks. Testing showed that under very high loads with hundreds of thousands of tasks in the run queue, the real-time tasks that would previously experience random jitter of up to around 300 milliseconds now goes down to less than 2 microseconds and even half a microsecond when tune.sched.low-latency is turned on. This will be sufficient to display one stats line per second with accurate measurements. - the idle connection cleanup task is now per-thread with no lock anymore, reducing the contention experienced on massively threaded systems with very large numbers of idle connections and short expirations (i.e. more CPU left for useful processing). - H3: traces now support a bit more granularity with "simple" and "advanced" verbosity levels to respectively report status lines and ful headers. - diag: some info emitted at diag-level via -dD were unfortunately emitted via ha_diag_warning() and counted as warnings, causing startup failures when combined with -dW to reject configs with warnings. One such diag info was the number of threads automatically created by the CPU policy. A new level was created in ha_diag_notice() to report info that is not a warning, and the CPU topology code now uses this. - memory profiling could count strdup() twice with certain libc that call their own malloc() function, making it difficult to diagnose certain leaks. The profiling code was improved with reentrance detection so that such allocations are only counted once. - pools: we figured that one pool was created with a space in its name, complicating the processing of "show pools" output. This was fixed and the set of allowed characters in pool name is now controlled at pool creation time so that it cannot happen again. - and a few cleanups and build fixes As I said, things are pretty calm in this version, so it's probably the easiest moment to start instrumenting your prod to switch one node to the 3.5-dev branch. Anyway it's already up an running on haproxy.org. The deprecated features marked for removal in 3.5 have not yet been removed (see https://github.com/haproxy/wiki/wiki/Breaking-changes for the status). This should happen soon though. 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.5/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.5/src/CHANGELOG Dataplane API : https://github.com/haproxytech/dataplaneapi/releases/latest OpenTelemetry : https://github.com/haproxytech/haproxy-opentelemetry 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/MEDIUM: mux_quic: prevent risk of infinite loop on recv OPTIM: mux_quic: remove QCS from recv_list on reset BUG/MINOR: mux_quic: do not interrupt recv on error/incomplete data BUG/MINOR: quic: fix Initial length value in sent packets MINOR: h3: extend trace verbosity MINOR: h3: trace HTTP headers on FE side MINOR: h3: trace HTTP headers on BE side BUILD: h3: fix compilation with USE_TRACE=0 BUG/MINOR: server: fix add server with consistent hash balancing BUG/MINOR: quic: fix rxbuf settings on backend side BUG/MEDIUM: mux_quic: fix freeze transfer after QCS rxbuf realign BUG/MINOR: hq-interop: reject too big content MINOR: hq_interop: do not rely on stream layer for HTX stline encoding BUG/MINOR: hq-interop: prevent reset if missing content-length BUG/MINOR: hq-interop: support full demux buf on large response BUG/MINOR: hq-interop: support response buffer wrapping Andrea Cocito (2): BUG/MEDIUM: h3: increment unknown request payload length REGTESTS: quic: test H3 request without content-length Christopher Faulet (18): BUG/MEDIUM: check: Skip tcpcheck post-config for external checks BUG/MEDIUM: check: Ignore small-buffer option when starting an external check MINOR: check: Don't dump buffers state in check traces for external checks BUG/MEDIUM: server/checks: Support healtcheck keyword on default-server lines BUG/MINOR: tcpcheck: Override external check if healthcheck section is set REGTESTS: checks: Add script for external healthchecks REGTESTS: Fix log matching in healthcheck-section.vtc DEBUG: stconn: Add a BUG_ON on shut flags when the endpoint is shut BUG/MINOR: http-ana: Remove a debugging memset on redirect BUG/MEDIUM: http-ana: Don't ignore L7 retry errors BUG/MINOR: mux-h1: Properly resolve file path for 'h1-case-adjust-file' BUG/MEDIUM: http-act: Make a copy of the sample expr in (set/add)-headers-bin OPTIM: mux-fcgi: Reorganise fcgi_conn structure to fill some holes BUG/MEDIUM: hlua: Properly report EOS when http applet exits BUG/MEDIUM: mux-fcgi: Truly drain outgoing HTX data when the stream is closed BUG/MEDIUM: mux-h2: Truly drain outgoing HTX data when the stream is closed BUG/MEDIUM: mux-spop: Truly drain outgoing data when the stream is closed BUG/MEDIUM: mux-quic: Drain the given amount of data in qcs_http_reset_buf() Karol Kucharski (1): BUG/MEDIUM: ktls: defer enabling TLS ULP on a socket until connected Olivier Houchard (17): BUG/MEDIUM: threads: Fiw build when using no thread BUG/MEDIUM: checks: Dequeue checks on purge MINOR: servers: Add a back-pointer to the server in srv_per_thread MEDIUM: servers: Move to a per-thread idle connection cleanup task BUILD: servers: Fix build with -std=gnu89 MINOR: tasks: Introduce __task_set_state_and_tid MINOR: tasks: Add __task_get_new_tid_field() MINOR: tasks: Introduce __task_get_current_owner MINOR: tasks: Use __task_get_current_owner() in task_kill. MINOR: tasks: Start using __task_set_state_and_tid() MEDIUM: tasks: Remove the per-thread group wait queue MINOR: tasks: Use __task_set_state_and_tid() in task_instant_wakeup() MINOR: tasks: Remove wq_lock and the per-thread group wait queues MEDIUM: tasks: Redispatch shared tasks when the thread is loaded BUG/MEDIUM: h3: Properly handle PUSH_PROMISE on backend connections BUG/MEDIUM: ssl: Don't free the early data buffer too early DOC: sched: Document the wait queue modifications Thayne McCombs (1): DOC: lua: remove incorrect init tags Tristan Madani (2): BUG/MINOR: hpack-tbl: add missing NULL check after hpack_dht_defrag() BUG/MEDIUM: mux-fcgi: fix uint16_t overflow in drl += drp William Lallemand (15): BUG/MEDIUM: acme: stuck ACME task when authz is already "valid" MINOR: acme: introduce acme_challenge_ready() for reuse outside the CLI MINOR: lua: add REGISTER_HLUA_STATE_INIT() to register state init callbacks MEDIUM: lua: move longjmp annotation macros to hlua.h MINOR: acme/lua: implement ACME.challenge_ready() Lua function MINOR: acme: publish ACME_NEWCERT event via event_hdl MINOR: acme: publish ACME_DEPLOY event via event_hdl EXAMPLES: lua/acme: add a dns-01 handler for Gandi LiveDNS API DOC: acme: add mentions of lua features MINOR: lua: export hlua_pusherror() and check_args() REORG: httpclient/lua: move the lua httpclient code to http_client.c MEDIUM: httpclient/lua: allow multiple requests from a single core.httpclient() instance MEDIUM: httpclient: set res.status to 0 upon SF_ERR_MASK DOC: httpclient: document status 0 on internal error EXAMPLES: lua/acme: fix acme-gandi-livedns.lua configuration example Willy Tarreau (24): BUG/MEDIUM: regex: initialize the match array earlier during boot BUG/MEDIUM: xprt_qmux: implement ->get_ssl_sock_ctx() to get the SSL laye CLEANUP: sessions: simplify the sess_priv_conns pool name MINOR: pools: reject creation of pools containing invalid chars in their name BUG/MINOR: acl: report "ACL" not "map" in ACL ID lookup failures MINOR: memprof: make in_memprof a bitfield instead of a counter MINOR: memprof: be careful to account allocations only once MINOR: errors: add ha_diag_notice() to report diag-level notifications BUG/MINOR: cpu-topo: use ha_diag_notice() to report thread creations DEBUG: cli: relax tid check in "debug dev task" for recent sched changes MINOR: debug: add "print" to "debug dev sched" BUG/MINOR: poller: fix wait time calculation that is always 1 extra ms BUILD: quic_pacing: add missing includes for api and activity in the file MINOR: task: move the profiling checks to the called functions not callers MINOR: task: add a new explicitly local tasklet wakeup function MINOR: task: make tasklet_wakeup() explicitly call _tasklet_wakeup_here() MINOR: task: make task_instant_wakeup() explicitly call _tasklet_wakeup_here() MEDIUM: task: make __tasklet_wakeup_on() only accept non-local threads MEDIUM: task: add a new flag TASK_RT to permit a task to skip the priority queue MINOR: debug: add "rt=1" to "debug dev task" to tune the RT flag CLEANUP: task: remove duplicated code in __tasklet_wakeup_after() BUILD: task: silence a build warning with threads disabled MINOR: task: do not try to redistribute the WQ when single-threaded MEDIUM: task: add a new tasklet class for real-time: TL_RT ---

