Hi,
HAProxy 3.5-dev7 was released on 2026/09/18. It added 85 new commits
after version 3.5-dev6. Only ~30 bug fixes this time.
However, there are some more visible changes, please read:
- the first one is the automatic chroot: haproxy now detects on startup
if the user has permission to create a chroot, and if so, tries do it.
This applies to privileged users, as well as unprivileged users on
linux when they can get CAP_SYS_CHROOT. In this cases haproxy will
try to use "chroot auto" (i.e. create a random temp dir and chroot
into it). We'll try to improve the situation by detecting if the
user can perform an unshare(CLONE_NEWUSER) and benefit from the
mechanism without being privileged at all (which already works for
explicit "chroot auto"). But this will probably require to rework
the code sequencing so that we can opportunistically try to chroot
instead of doing it only when we believe we can.
It's important that you test this in your environments. We *do* expect
some surprises, such as a root user without capabilities, or maybe some
interference from seccomp or other mechanisms, as well as containers.
To be clear, my ultimate goal is to try to increase the security level
by default without the user having to think about it (i.e. continue to
simplify the config and being secure by default).
This will definitely break some setups which used to rely on UNIX sockets
on "server" lines, or on external checks. These ones will need to pass
an explicit "chroot /" to indicate they do not want to chroot (supported
since 3.4, with a warning when missing). But I prefer users who have a
good reason for running insecure to say so rather than all other ones
doing it unknowingly.
- second theoretically visible change: we've temporarily reverted the
"filter-sequence" directive. It was added to 3.4 and will also be
temporarily reverted from there, where it was placed to ease the
transition to the improved filters API allowing to arrange filter
sequencing by direction, in prevision for the decompression that is
now merged in 3.5. While working on improving the API, we found some
dead ends that are not visible yet but that will no longer possible to
work around if users start to rely on filter-sequence in its current
form. We're not yet certain of the final syntax (though we have plans)
so we'd rather disable it to make sure nobody uses it while it's not
needed, rather than cause a harder breakage later when users can no
longer avoid it. The goal is to get all of this sorted for 3.5, and
depending on how things go, we may backport the user-visible changes
to 3.4 to ease the transition.
The rest is lighter:
- we had long planned to make the HTTP parsers converge their semantic
layers so that each time we fix a bug in one, we fix it for all versions
at once. That's a tough work, but it has started with the trailers (the
easy part that served as an exercise). So now, h1,h2,h3 and fcgi use the
same function to process trailers on the rx path. One immediately visible
effect is that H1 and FCGI now benefit from extra protections that would
previously only be in H2 and H3 (reject forbidden names such as connection
or content-length). The rejected cases are so gross that there's no need
for an option to bypass the check, so no breakage is expected here.
- the jwt_verify() converter no longer supports the "none" algorithm that
documention says should not be supported.
- a new internal API to submit a job to another thread or thread group was
implemented. It will be needed for situations where we run in split FD
tables per thread group, so that certain CLI commands can retrieve info
about FDs belonging to foreign groups (e.g. "show fd", "show sess" etc).
The listeners switched to it for the "disable/enable/shutdown" operations,
that would previously rely on a hand-rolled implementation.
- as requested and discussed in GitHub issue #3451, a pair of identifiers
are now created for the master and the worker process. The master's one
persists across reloads while the worker's is renewed. The worker's may
also be forced via "worker-id" in the config. The goal is to use them to
distinguish processes within a cluster as well as process generations
across deployments / reloads. The equivalent "master_id" and "worker_id"
sample fetch functions were added to retrieve them (e.g. for logs), and
they can be seen on "show info" and on the stats page when
"stats show-node" is used.
- the CLI's "show ring" now supports raw mode ("-r") which just undoes
the safe "-s". This will permit API tools to start using it early in
anticipation for a future change of the default.
- a new "be_sort" converter permits to order input bytes read by blocks
or 1, 2, 4, or 8 bytes at once in big-endian order (i.e. network order),
and sort them. This is useful for comparing supported algorithms, curves
etc in SSL regardless of the ordering.
- some HTX updates
- 9 new reg tests were added for various things, and some build fixes,
cleanups and doc updates were added as well.
Some changes are visible at the config level and startup time, so please
check that we didn't break anything for you (or report it so that we can
try to find a better solution).
Next week, some of us will be at Kernel Recipes, so please expect a bit
more latency in responses and be kind with those who respond, keeping in
mind that they'll be handling more than their usual share of it ;-)
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 (5):
BUG/MINOR: h3: reject truncated frames with mandatory payload
BUG/MEDIUM: h3: do not block FIN on empty DATA frame
BUG/MINOR: h3: handle empty HEADERS frame as specified
BUG/MINOR: h3: handle unknown frame type on request stream as specified
BUG/MINOR: h3: only increment frame type counter on new header
Asjid Kalam (1):
IMPORT: uslz: reject codes from an empty distance table
Christopher Faulet (19):
BUG/MEDIUM: hlua: Never release a cosocket applet from the GC
BUG/MINOR: mux-h1: Return an error on trailers if last chunk is unfinished
BUG/MINOR: hlua: Always return nil if there is no data to dup for HTTP
messages
BUG/MEDIUM: htx: Don't reset flags when source must be preserved during
transfer
BUG/MINOR: flt-http-comp: Rely on htx_set_eom() to restore EOM flag
MINOR: httpclient: Don't manually set HTX_FL_EOM flag after calling
htx_xfer()
MINOR: htx: Remove htx_xfer_blks function
CLEANUP: htx: Remove ref to EOM block on HTX_FL_EOM flag comment
DOC: htx: Fix comment of htx_expect_more() function
REORG: htx: Move functions to deal with first block after ones about next
block
MINOR: mux-h1: loop on HTX blocks using _blk() functions to look for WS
key
SCRIPTS: run-regtests: Increase internal buffer size used for logs
BUG/MEDIUM: cli: Don't parse next command if input buffer is empty
BUG/MEDIUM: cli: Don't read a command or payload line into a full buffer
BUG/MINOR: cli: Reject payload with no command
BUG/MEDIUM: htx: Reserve a block descriptor for zero-sized blocks
CLEANUP: stream: Remove an excess newline in the stream dump
BUG/MEDIUM: tcp-rules: Don't restart tcp-request content evaluation on
yield
MAJOR: filters: Revert the filter-sequence directive
Frederic Lecaille (7):
BUG/MINOR: quic: leak of the NEW_TOKEN frame on token generation failure
MINOR: quic: implement the AEAD integrity limit
BUG/MEDIUM: map: do not overwrite the fetch context in pat_match_regm()
REGTESTS: map: check map_regm inside an ACL over an iterating fetch
BUG/MINOR: pattern: do not match a string with an embedded \0 on its
prefix
REGTESTS: http-rules: check "-m str" on a sample with an embedded \0
BUG/MINOR: sample: reject a \0 byte in url_dec, json_query and jwt_*_query
Manu Nicolas (1):
BUG/MEDIUM: http-ana: apply tunnel timeout with data filters
Olivier Houchard (8):
BUILD: fd: Make sure to include sched.h
BUG/MINOR: cli: Make sure two instances of _getsocks don't run
BUG/MEDIUM: listener: Don't drop suspend/resume deferred requests
MEDIUM: twork: Introduce a new cross-thread/thread-group deferred work API
MEDIUM: listener: make the rx_agent use the generic twork API
MINOR: fd: add fd_tables_are_split() to test for split FD tables
BUG/MEDIUM cli: dump other thread groups' FDs from their own threads
BUG/MINOR: stream: resolve foreign groups' addresses for "show sess"
Remi Tricot-Le Breton (3):
BUG/MINOR: ssl: don't pass the address of a size_t as an int* to OpenSSL
MEDIUM: jwt: Reject "none" alg in jwt_verify by default
BUG/MINOR: ssl: Fix leak of ca_list in cafile_entry
William Lallemand (5):
BUILD: fd: unshare is not available on NetBSD
BUILD: ssl: ASN1_STRING_length() is deprecated since OpenSSL 4.1
BUG/MEDIUM: ssl: don't set a 0 timeout on an expired TLS session
MINOR: sample: add the "be_sort" converter
REGTESTS: converter: add a test for the "be_sort" converter
Willy Tarreau (34):
DOC: config: clarify tune tune.bufsize doc regarding various limits
BUG/MINOR: stream/debug: harden the stream dump function regarding signals
MINOR: stconn: prefer to replace endpoints rather than detaching them
MINOR: ring: add "-r" to "show events" to dump in raw mode (undoes "-s")
MINOR: ring: permit to combine options on "show events"
MINOR: ring/cli: improve the "show events" parser regarding options
MINOR: ring/cli: also support "show events -h" to display the help
MINOR: http: define new HTTP status codes for parsers
MINOR: http-htx: add a new generic trailers parser
REGTESTS: http-messaging: add tests for the H2 and H3 trailers
MEDIUM: mux-h2: rely on the generic trailers parser
MINOR: mux-h2: report more accurate traces and glitches on trailers errors
CLEANUP: h2: get rid of the now unused h2_make_htx_trailers()
MEDIUM: h3: rely on the generic trailers parser
REGTESTS: specify explicit chroot in confs using unix-stream servers
MAJOR: startup: use chroot auto by default when available
REGTESTS: http-messaging: add tests for the H1 trailers
MINOR: http-htx: pass extra flags to the HTTP trailers parser
MINOR: http-htx: condition uppercase acceptance in trailer names to
HTTP_PF_UPCASE_OK
MEDIUM: h1: switch to the generic trailers parser
REGTESTS: update trailers tests to cover H1's refusal of forbidden names
MINOR: htx: don't reserve a block when there is no free space left
DOC: configuration: clarify the validity ranges of sample types
BUG/MINOR: proxy: pass PR_FL_DEF_EXPLICIT_MODE through cascaded defaults
MINOR: promex: properly use alt_name and val instead of hard-coded values
MINOR: mworker: assign a unique ID to the master process
MINOR: config: add a "worker-id" global keyword to identify the worker
MINOR: sample: add the "master_id" and "worker_id" sample fetches
MINOR: stats: report the master and worker IDs in "show info"
MINOR: promex: expose the master and worker IDs as labels
MINOR: extcheck: pass the master and worker IDs to external checks
MINOR: stats: report the process IDs on the HTML page with "stats
show-node"
REGTESTS: mcli: check the master and worker unique identifiers
DOC: config: fix indent issue introduced with worker id
Youngkwang Lee (2):
BUG/MEDIUM: http_act: fix normalize-uri normalizer selection with a
condition
REGTESTS: uri_normalizer: test a normalizer used with a condition
---