Hi,
HAProxy 3.3-dev12 was released on 2025/11/08. It added 67 new commits
after version 3.3-dev11.
Roughly 1 third are bug and build fixes, nothing really outstanding in
this area, except maybe the crash at boot that was affecting non-x86
platforms in the previous version, and one that could also crash some
x86 at -O3 at boot (all due to alignment issues that were now addressed).
So if you wanted to try a previous version and it didn't even start, it's
time to give it a try again.
The main visible changes in this version are:
- automatic certificate generation for ACME when no cert is available.
It will finally no longer be necessary to pre-generate an expired
cert in new VMs or containers ;-)
- some more warnings about global keywords that are incompatible with
command-line keywords, such as "daemon" when combined with "-Ws", or
the "master-worker" alone while -W ought to be used instead.
- the QUIC configuration was refined a bit: servers no longer accept
QUIC configuration if QUIC was not compiled in; SSL is implicit on
servers when QUIC is enabled, and ALPN is automatically set to h3
by default.
- handling of empty arguments in the config file was finally fixed.
Using an empty var at the end of an argument will no longer result
in it being merged with the next argument, and unknown vars will no
longer be silently skipped. Unresolved variables will be explicitly
designated, and those looking like a known one will result in the
closest match being suggested (e.g. "HAPROXY_LOCALPEER" if instead
"HAPROXY_LOCLA_PEER" was used). Initially I wanted to do that early
in 3.3 to backport it to 3.2, but I suspect we risk breaking more
confs than we'll fix due to the temporary workaround that have stayed
there for too long and been lenient on the syntax. Thus I'd rather
keep that away from 3.2 for now. If your config contains "${FOO}"
that expects to drop the field when FOO is empty or undefined, it's
necessary to fix it according to the doc which suggests to use
"${FOO[*]}" to drop empty fields, otherwise an error will be
reported (corresponding to the pre-3.2 deprecation warning).
- a code review revealed that 2 global config keywords would accept
crazy values (e.g. negative or large enough to cause overflows)
that resulted in a non-functional process or a crash at boot. Saner
but high limits were set: 100 for tune.stick-counters, 1 million for
tune.maxpollevents.
- some improvements on the peers implementation which no longer acks
updates during full resync as they're not necessary and needlessly
eat resources on the peer, slowing it down. Traces were improved as
well. A few points were also improved on the stick-tables expiration
to further save a little bit of CPU.
- some new sample fetch functions "{req,res}.bytes_{in,out}" to get
the number of input/output bytes on each channel. Previously it was
never clear to know whether byte counters were counted in or out,
which does change e.g. with compression or caching. Now it will be
more explicit. The same are also collected in the stats so that it's
finally possible to know how much was received/sent by proxies.
- the aes_gcm_dec() and aes_gcm_enc() converters now accept an optional
AAD argument that's sometimes required with authentication.
The rest is essentially infrastructure updates. The outgoing connection
code was adjusted a bit to permit backend QUIC to properly sequence 0-RTT
(which should probably be merged next week). Some code cleanups were done,
and the build-ssl script was updated to support building for FIPS and to
fix rpath in AWS-LC. The CI updated to macos-26.
In addition to 0-RTT arriving next week, there are some QUIC fixes pending
for the frontend where a rare crash can occur on connection ID handling.
Some more architectural reviews of stick-tables and peers are planned for
next week, which may possibly result in a few fixes or minor updates. Along
some tests, I once managed to see a server with a negative connection count
but for now I couldn't reproduce it. It could be something that affects
older versions, so if anyone faces this (or an undeletable server) and ends
up with a reliable reproducer, feel free to share. Other than that, for now
it looks quite good and I'm confident that we'll release by the end of the
month (probably last week).
I noticed that the ratio of QUIC requests on HAProxy.org has significantly
increased with the last version, now representing 33% of the SSL traffic,
which is quite high considering that a large number of accesses are git
clones. This is probably as a result of the recent fixes, that make
browsers more prone to switching to QUIC. Even AI bots seem to be using it
now (not sure this one is a good news though)!
If you're thinking about giving 3.3-dev a try and are constantly postponing
by lack of time, please just pick this one and share your observations. We
can still do a few changes before the release.
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 (8):
MINOR: quic: enable SSL on QUIC servers automatically
MINOR: quic: reject conf with QUIC servers if not compiled
OPTIM: quic: adjust automatic ALPN setting for QUIC servers
OPTIM: backend: skip conn reuse for incompatible proxies
BUG/MINOR: quic: fix crash on client handshake abort
MINOR: quic: do not set conn member if ssl_sock_ctx
MINOR: quic: remove connection arg from qc_new_conn()
MINOR: quic: remove <mux_state> field
Ben Kallus (1):
IMPORT: cebtree: Replace offset calculation with offsetof to avoid UB
Christopher Faulet (16):
MINOR: stconn: Add counters to SC to know number of bytes received and
sent
MINOR: stream: Add samples to get number of bytes received or sent on
each side
MINOR: counters: Add req_in/req_out/res_in/res_out counters for
fe/be/srv/li
MINOR: stream: Remove bytes_in and bytes_out counters from stream
MINOR: counters: Remove bytes_in and bytes_out counter from fe/be/srv/li
MINOR: stats: Add stats about request and response bytes received and sent
MINOR: applet: Add function to get amount of data in the output buffer
MINOR: channel: Remove total field from channels
DEBUG: stream: Add bytes_in/bytes_out value for both SC in session dump
MEDIUM: stktables: Limit the number of stick counters to 100
BUG/MINOR: config: Limit "tune.maxpollevents" parameter to 1000000
MINOR: peers: Improve traces for peers
MEDIUM: peers: No longer ack updates during a full resync
MEDIUM: peers: Remove commitupdate field on stick-tables
BUG/MEDIUM: peers: Fix update message parsing during a full resync
MINOR: sample/stats: Add "bytes" in req_{in,out} and res_{in,out} names
Damien Claisse (1):
BUG/MINOR: resolvers: ensure fair round robin iteration
Maximilian Moehl (1):
BUG/MEDIUM: mux-h1: fix 414 / 431 status code reporting
Olivier Houchard (6):
BUG/MEDIUM: server: Add a rwlock to path parameter
BUG/MEDIUM: server: Also call srv_reset_path_parameters() on srv up
BUG/MEDIUM: stick-tables: Make sure we handle expiration on all tables
MEDIUM: stick-tables: Optimize the expiration process a bit.
MEDIUM: backend: Defer conn_xprt_start() after mux creation
BUG/MEDIUM: stick-tables: Make sure updates are seen as local
William Lallemand (18):
MINOR: sample: optional AAD parameter support to aes_gcm_enc/dec
REGTESTS: converters: check USE_OPENSSL in aes_gcm.vtc
SCRIPTS: build-ssl: allow to build a FIPS version without FIPS
SCRIPTS: build-ssl: fix rpath in AWS-LC install for openssl and bssl bin
CI: github: update to macos-26
MEDIUM: cfgparse: deprecate 'master-worker' keyword alone
MEDIUM: cfgparse: 'daemon' not compatible with -Ws
DOC: configuration: deprecate the master-worker keyword
MEDIUM: ssl/ckch: use ckch_store instead of ckch_data for ckch_conf_kws
MINOR: acme: generate a temporary key pair
MEDIUM: acme: generate a key pair when no file are available
BUILD: ssl/ckch: wrong function name in ckch_conf_kws
BUILD: acme: acme_gen_tmp_x509() signedness and unused variables
BUG/MINOR: acme: fix initialization issue in acme_gen_tmp_x509()
BUILD: ssl/ckch: fix ckch_conf_kws parsing without ACME
DOC: acme: crt-store allows you to start without a certificate
BUG/MINOR: acme: allow 'key' when generating cert
BUG/MINOR: acme: wrong dns-01 challenge in the log
Willy Tarreau (16):
BUG/MAJOR: stats-file: fix crash on non-x86 platform caused by unaligned
cast
OPTIM: proxy: move atomically access fields out of the read-only ones
BUG/MEDIUM: mux-h2: make sure not to move a dead connection to idle
BUG/MEDIUM: connections: permit to permanently remove an idle conn
MINOR: server: move the lock inside srv_add_idle()
BUG/MEDIUM: server: close a race around ready_srv when deleting a server
BUG/MINOR: config: emit warning for empty args when *not* in discovery
mode
BUG/MEDIUM: config: solve the empty argument problem again
MEDIUM: config: now reject configs with empty arguments
MINOR: tools: add support for ist to the word fingerprinting functions
MINOR: tools: add env_suggest() to suggest alternate variable names
MINOR: tools: have parse_line's error pointer point to unknown variable
names
MINOR: cfgparse: try to suggest correct variable names on errors
BUG/MEDIUM: proxy: use aligned allocations for struct proxy
BUG/MEDIUM: proxy: use aligned allocations for struct proxy_per_tgroup
BUG/MINOR: acme: avoid a possible crash on error paths
---