Hi,

HAProxy 3.5-dev9 was released on 2026/10/14. It added 239 new commits
after version 3.5-dev8.

This release contains ~56 bug fixes, 3 of which need particular care:

  - quic: a risk of crash exists in certain conditions of a terminated
    stream. To be honest I don't remember he details, it's super rare
    but did happen (was reported by a user).

  - HTTP/2: an HTTP/2 PING frame cannot be entirely consumed until it is
    complete, and the presence of an incomplete frame is sufficient to
    cause a wakeup, preventing the CPU from going idle until the entire
    frame is received, and resulting in a 100% CPU measurement for as long
    as the peer keeps the connection open without completing the frame (or
    until "timeout http-request" expired, when one is set). The performance
    impact is moderate and depends on the ratio of such connections among
    all concurrent connections. Partial PING frames are now detected as
    short reads like the other frame types, so the tasklet goes back to
    sleep until the rest of the frame arrives. The handling of short reads
    was fixed in 2.5, but PING was missed; it only became a problem in 3.1
    when the tasklet wake-up logic changed. As a workaround on an older
    build, setting "timeout http-request" to a low value such as 1-5
    seconds limits the CPU consumption. A CVE was request, this affects
    stable versions as well.

  - HTTP/1.1: for chunked messages, when a chunk-size line was longer than
    the input buffer, the parser made no progress, waiting for the end of
    the line. So no data was consumed, the buffer was full and could not be
    extended: the same bytes were retried endlessly with no request ever
    processed on it, preventing, as for the H2 multiplexer issue, the CPU
    from going idle. Here too, the impact is moderate and depends on the
    ratio of such connections among all concurrent connections. A parsing
    error (HTTP 400) is now reported as soon as the parser determines that
    the line cannot possibly fit, using the same full-buffer detection that
    already exists for oversized headers and trailers. Reported with a fix
    proposal by Adam Crawford. A CVE was request, this affects stable
    versions as well.

Aside this, there's fortunately quite some new stuff:

- HTTP: some users trying haproxy as an AI gateway experienced huge
  latencies (milliseconds) due to missing "option http-no-delay". It
  turns out that in the case of server-streamed events (SSE), there's a
  recognizable content-type ("text/event-stream") in the response, so we
  now check for it in order to automatically switch to low-latency mode.
  One less option to care about, and it also automatically adapts to the
  response contents so that we don't degrade a whole proxy when a single
  URL requires it. A small utility (dev/sse-latency) was also developed to
  measure the latency across a gateway such as haproxy, showing a few tens
  of microseconds in idle (actually the time it takes to wake the CPU up
  from idle and boosting its frequency between messages) and no longer
  anything expressed in milliseconds.

- OCSP: a new "do-ocsp-request" tcp/http action was introduced, to perform
  an OCSP request on the client certificate on the fly so that it's
  possible to verify its status before going further, and even to just
  deny the request (by default) in case of bad status.

- dynamic backends: new CLI actions were added to greatly simplify the
  management of dynamic backends. All of these rely on a new background
  task to complete the operation, waiting for remaining references to
  disappear, so the script/API client will no longer need to poll for
  each server removal one at a time nor have to care about the proper
  completion of an operation:
  - purge server <be>/<srv>: just like "del server" except that the
    action succeeds and programs the removal in background. Enabling
    the server again cancels the operation.
  - purge all servers <be>: just like "purge server", but does it for
    all servers in the backend, and ignores those that cannot be deleted
    due to configuration constraints.
  - purge backend <be>: like "del backend" but deletes all servers in
    background first, then programs the deletion of the backend. A
    publish/unpublish command will cancel the operation.
  - wait ... srv-unknown / wait ... be-unknown: waits for the server
    or backend name to no longer be found (i.e. guaranteed removal).

- debug: haproxy's symbols table is now stored compressed at build time
  inside the executable (quite small), is accessible from gdb even on
  stripped binaries, but is also accessible from haproxy itself, meaning
  that warnings and panic dumps will now show much more precise backtraces.
  Also, the "set-dumpable" keyword now automatically disables the implicit
  automatic chroot, otherwise there's no way to dump a core anymore.

- filters: the new API allowing a filter to decide where it will register
  itself with regards to the other ones is finally in place, and with it,
  the filter-sequence directives have been re-enabled. The default sequence
  matches the vast majority of use cases, and it is possible to reposition
  certain filters (e.g. one might want to decompress after caching instead
  of before so as to store smaller objects). It also allows to instantiate
  multiple occurrences of the trace filter each at their specific location
  (before or after an existing filter family), and to separately configure
  and enable a filter. This is also particularly important with dynamic
  backends so that all this stuff is correct by default or can be properly
  configured in the relevant defaults sections. Most users won't notice
  (which is also why it was tricky), but it means that this part is finally
  expected to be over.

- SPOE: a new "on-switching-rules" event permits an SPOA to influence the
  routing decision to a backend, by being called just at the moment the
  backend selection is performed.

- the remaining old keywords in cfgparse-global and cfgparse-listen were
  finally migrated to the keyword registration API meaning that we no
  longer need to keep some lists of exceptions for historic keywords that
  were not listed anywhere. "haproxy -dKcfg" now lists something like 125
  extra keywords that were not referenced before, which will be helpful to
  those watching for new keywords, but more importantly, the legacy code
  no longer exists to serve as example when new features are developed.
  It's possible that some more dead code could be removed but that was not
  deeply explored yet.

- a new section "loggers" was added, in order to group multiple logging
  destinations and reference them in "log" directives and "do-log" actions.
  This will permit to force certain logs to be emitted to certain
  destinations on certain conditions.

- Lua: a new PROXY event family was added to watch for backend addition/
  deletion.

- SSL: a new curve2name() converter was added to convert curve names
  between the various standards, e.g. "prime256v1" and "P-256" are the
  same.

- CLI: "show info" now shows the SSL library's FIPS mode status.

- the rest is as usual: regtests, doc, build fixes, and a bunch of doc
  updates.

As a reminder, if you're running a stable version, please see the
respective announcements and update yours regarding the two vulnerabilities
above.

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 (41):
      BUG/MINOR: proxy: add PR_CAP_LB for dynamically added backend
      BUG/MINOR: server: fix "del server" description
      BUG/MINOR: cli: update wait help usage
      BUG/MEDIUM: server: remove immediately from GUID tree on delete server
      DOC: server: explicit refcount interaction in "del server"
      BUG/MINOR: hq-interop: prevent double EOM on request with standalone FIN
      BUG/MINOR: ssl: fix trace crash on FE conn release in io cb
      BUG/MINOR: ssl: fix trace crash on BE conn release in io cb
      BUG/MAJOR: mux-quic: prevent crash on QCS already set for purging
      BUG/MINOR: mux_quic: prevent purgeable QCS lingering
      BUG/MINOR: mux_quic: extend FINAL_SIZE_ERROR detection on stream
      BUG/MINOR: mux_quic: report conn error on RESET_STREAM fctl violation
      BUG/MEDIUM: mux_quic: account discarded data in connection flow control
      BUG/MINOR: mux_quic: account data in conn fctl on early detach
      BUG/MINOR: h3: reject frames with truncated header
      BUG/MINOR: h3: close connection on GOAWAY frame too long
      BUG/MINOR: h3: reject RS/SS for QPACK uni streams
      BUG/MEDIUM: mux_quic: notify stream on RESET_STREAM reception
      BUG/MEDIUM: h3: fix end-of-input report on DATA wrapping
      MEDIUM: h3: do not close conn on unaligned non DATA frame
      BUG/MEDIUM: h3: fix incorrect DATA size block on DEM FULL
      OPTIM/MINOR: server: restrict <all_servers> list usage
      MINOR: server: rename <all_servers> list to <servers_to_init>
      MINOR: server: refactor cli_find_server()
      MINOR: server: extract unregistering from "delete server" CLI parser
      MINOR: proxy: define purge task and purge servers list
      MEDIUM: server: implement "purge server" CLI
      MINOR: server: set maintenance mode on "purge server"
      MINOR: proxy: yield during servers purge
      MINOR: cli: refactor CLI wait command parser
      MINOR: cli: implement wait srv-unknown
      OPTIM/MINOR: server: remove unnecessary server lookup during purge
      REGTESTS: server: test "purge server" CLI command
      MEDIUM: server: implement "purge all servers" CLI
      MINOR: server: yield during "purge all servers"
      REGTESTS: server: test "purge all servers" CLI command
      MINOR: proxy: extract proxy runtime deletion in a specific function
      MEDIUM: proxy: implement purge backend
      MINOR: cli: implement wait be-unknown
      OPTIM/MINOR: proxy: remove unnecessary lookup during purge
      REGTESTS: proxy: test "purge backend" CLI

Aurelien DARRAGON (11):
      BUG/MINOR: log: fix erroneous error message in log-steps parser
      MINOR: log: add "loggers" section
      MINOR: log: support 'to' parameter for "log" directive
      MINOR: log: support explicit <loggers> list for do_log_ctx()
      MINOR: log: support 'to' parameter fo do-log action
      DOC: config: document new "loggers" section and relevant uses
      BUG/MINOR: hlua: assume proxy_find_by_id() may return NULL on previously 
existing server
      MINOR: event_hdl: add PROXY family events
      MINOR: proxy: add e_sub proxy subscrition list
      MINOR: event_hdl/proxy: publish EVENT_HDL_SUB_PROXY_{ADD,DEL,PUB,UNPUB} 
events
      MINOR: hlua: expose PROXY event family through Lua

Benedict Weis (1):
      MEDIUM: spoe: add the "on-switching-rules" event

Christopher Faulet (65):
      BUG/MINOR: spoe: Fix the message list splice with an empty list
      BUG/MINOR: flt-decomp: Fix the decompression filter keyword list name
      MEDIUM: flt-http-comp: Enable compression directions from algorithms
      MINOR: flt-http-comp: Use compression options as filter config
      BUG/MINOR: flt-http-comp: Enable implicit filters independently per 
direction
      MINOR: flt-http-comp: Don't uselessly init a compression filter
      MINOR: flt-decomp: Don't instantiate a filter without applicable direction
      MINOR: bwlim: Use a different filter ID for in/out filters
      MINOR: fcgi: Move application validation to the post-check stages
      MINOR: filters: Introduce filter classes and per-side class ordering
      MINOR: filters: Add per-proxy filter instance storage and lookup
      MINOR: filters: Inherit filter instances from defaults sections
      MINOR: filters: Add instance parsers for the built-in classes
      MEDIUM: filters: Parse and finalize filter-config instances
      MINOR: filters: Add filter-enable and filter-disable directives
      MINOR: filters: Add per-side filter-sequence constraints
      MINOR: filters: Mirror implicit filters as filter instances
      MINOR: filters: Expose classes and instances through the CLI
      MINOR: filters: Reject filter-* directives in anonymous defaults
      MINOR: filters: Restrict defaults inheritance with explicit filter 
directives
      MINOR: filters: Reject mixing legacy and filter-* directives
      MINOR: filters: Maintain a global instance list per proxy
      MINOR: filters: Use global instance order for startup operations
      MINOR: filters: Support global instance sequencing
      MINOR: filters: Expose global filter ordering through the CLI
      MINOR: filters: Use a proxy flag to detect use of legacy 'filter' 
directive
      MINOR: filters: Don't finalize filter instances in legacy mode
      MINOR: filters: Add helpers to iterate and find filter configurations
      MINOR: filters: Add flt_has_filter() and use it in proxy_finalize()
      MINOR: filters: Select legacy or instance model in lifecycle callbacks
      MEDIUM: filters: Attach filter instances to streams
      MEDIUM: cache: Resolve cache rules during the check stage
      MINOR: cache: Use the filter helpers for cache checks and post-check
      MINOR: fcgi-app: Use the filter configuration helpers for lookups and 
checks
      MINOR: bwlim: Look up the bandwidth filter with the filter helpers
      MINOR: flt-decomp: Use the filter helpers for implicit decompression 
checks
      MINOR: flt-http-comp: Use the filter helpers for implicit compression 
checks
      MINOR: spoe: Use the filter configuration helpers for lookups and checks
      REGTESTS: filters: Add a test for per-proxy stream filter ordering
      REGTESTS: filters: Exercise Lua inheritance and state selection
      REGTESTS: filters: Exercise stream isolation across backend modes
      REGTESTS: filters: Exercise Lua callback resumption
      REGTESTS: filters: Exercise Lua filters across HTTP retries
      REGTESTS: filters: Exercise Lua probes around mixed built-in filters
      REGTESTS: filters: Exercise TCP Lua payload chains and sequencing
      REGTESTS: filters: Exercise per-thread Lua instance state
      REGTESTS: filters: Record Lua callback waits across backend EOF
      REGTESTS: filters: Check non-HTX Lua filters in HTTP chains
      MINOR: filters: Add a global option to enforce the legacy filter api
      DOC: filters: Document the filter instance mode and the legacy mode
      DOC: lua: Document the filter instance declaration of Lua filters
      CLEANUP: filters: Use the stream filter instance wording in comments
      MINOR: filters: List the filter classes in haproxy -vv
      DOC: config: Review "Supported filters" section
      MINOR: lua: Protect the common Lua state during a runtime filter deinit
      MEDIUM: stream: Hold a reference on the frontend during stream_free()
      MINOR: applet: Add a destroy callback to the applets
      BUG/MEDIUM: spoe: Let an agent outlive its applets during a backend 
deletion
      MEDIUM: filters: Activate the instances inherited by dynamic backends
      DOC: filters: Document how to port an existing filter
      BUG/MEDIUM: mux-h1: also release the embryonic stream when the error is 
empty
      BUG/MINOR: http-fetch: don't report pseudo-headers in TCP mode
      BUG/MEDIUM: mux-h1: only accept the H2 preface on the first request
      REGTESTS: http-messaging: Fix http_fail_cnt_body to succeed with small 
timeouts
      BUG/MAJOR: h1-htx: report an error on a too long chunk-size line

Frederic Lecaille (2):
      BUG/MEDIUM: ssl: crt-list ciphers ignored with AWS-LC
      BUG/MEDIUM: ssl: crt-list curves ignored with AWS-LC

Lukas Tribus (1):
      MINOR: doc: elaborate on diagnostic mode behavior

Olivier Houchard (13):
      CLEANUP: sym: move symbol resolution out of tools.c
      MINOR: sym: add an in-process symbol table for backtraces
      MINOR: sym: collect the symbols known to the dynamic linker
      MINOR: sym: add helpers to collect the symbols of an ELF image
      IMPORT: xz: import the xz-embedded decoder
      MEDIUM: sym: store a compressed symbol table in a loadable section
      MINOR: sym: read local symbols and debug info from ELF files
      MINOR: sym: also read the compressed symbol tables from the ELF files
      OPTIM: sym: skip the embedded table when the file provided the symbols
      MINOR: makefile: add CROSS_TOOLCHAIN to prefix the target's tools
      BUILD: Hopefully fix build on FreeBSD
      BUILD: sym: Define HA_HAVE_DL_ITERATE_PHDR on FreeBSD
      BUG/MEDIUM: listener: Consider maxconn before waking listeners

Remi Tricot-Le Breton (10):
      MINOR: ocsp: Remove free of main structure from ssl_sock_free_ocsp_data
      MINOR: ocsp: Send OCSP response status back to caller
      MINOR: ocsp: Raise specific ocsp error code in ocsp parsing/verifying 
functions
      MINOR: ocsp: Dup OCSP_CERTID in ssl_ocsp_create_request_details
      MEDIUM: ocsp: Create new do-ocsp-request action
      MINOR: ocsl: Add 'inapplicable' return code to client certificate ocsp 
check
      DOC: ocsp: Add doc for the new 'do-ocsp-request' action
      REGTESTS: ocsp: Add 'do-ocsp-request' tests
      BUG/MINOR: ssl: Fix potential NULL-deref in "dump ssl cert" with AWS-LC
      MINOR: cache: Remove a useless variable in http_action_req_cache_use

William Lallemand (21):
      BUILD: ssl: fix build without USE_OPENSSL + clear_ocsp_clt_check_ctx
      REGTESTS: cli: don't check the HAProxy string
      MINOR: ssl: support curve fetches with AWS-LC API 30
      BUILD: ssl: avoid mixed declarations in the AWS-LC curve fetch
      CI: github: test AWS-LC 3.x and 4.x LTS branches
      CI: github: test the latest AWS-LC release on development branches
      CI: github: cache QuicTLS builds
      CI: github: move wolfSSL 5.7.0 testing to a nightly workflow
      BUG/MINOR: ssl: don't uppercase the native group name
      DOC: ssl: clarify the NID-based curve fetch branch
      BUG/MINOR: ssl: use standard names for X25519 and X448 groups
      MINOR: ssl: split curve names into ANSI, IANA and NIST columns
      MINOR: ssl: skip unavailable NIDs in curves2nid lookup
      MINOR: ssl: complete registered group names and library NID mappings
      MINOR: ssl: add curve2name converter
      MINOR: ssl: accept integer group IDs in curve2name
      MINOR: stats: report the SSL library FIPS mode in "show info"
      REGTEST: ssl: require OpenSSL 1.1.1 for crt-list ciphersuites tests
      DOC: make: fix EXTRA_MAKE fragment filename
      BUG/MINOR: cfgparse-global: only warn when "localpeer" is set together 
with -L
      DOC: configuration: document AWS-LC compatibility restrictions

Willy Tarreau (70):
      DEV: sse-latency: add a latency measuring tool for SSE response streams
      MINOR: http-ana: automatically enable http-no-delay for streaming events 
(SSE)
      DEBUG: support reading set-dumpable from HAPROXY_FORCE_DUMPABLE
      BUG/MAJOR: cfgparse: properly check userlist section when scanning 
keywords
      BUG/MINOR: cfgparse-global: add missing gotos to error label in 
max-spread-checks
      BUG/MINOR: cfgparse-global: add missing calloc() check for the global 
description
      BUG/MINOR: cfgparse-listen: release the previous description of the proxy
      BUG/MINOR: cfgparse-listen: fix the argument checked by "email-alert"
      BUG/MINOR: cfgparse-listen: fix quoting of the condition conflict warning
      BUG/MINOR: cfgparse-global: reject extra arguments to numa-cpu-mapping 
and anonkey
      BUG/MINOR: cfgparse-listen: always reject extra arguments to "persist"
      BUG/MINOR: cfgparse-listen: don't lose the errors reported while creating 
a proxy
      BUG/MINOR: cfgparse-listen: properly reject extra args in a backend 
section
      BUG/MINOR: proxy: also look for the closest option among cfg_opts3
      BUG/MINOR: cfgparse-listen: complete the list of options for the 
suggestions
      CLEANUP: proxy: adapt the error message for removed "option transparent"
      MINOR: cfgparse: expose the keyword modifier to the keyword parsers
      CLEANUP: cfgparse-global: move the argument-less boolean options to a 
parser
      CLEANUP: cfgparse-global: move "set-dumpable" to its own parser
      CLEANUP: cfgparse-global: move "uid", "gid", "user" and "group" to its 
own parser
      CLEANUP: cfgparse-global: move "external-check" to its own parser
      CLEANUP: cfgparse-global: move "cluster-secret" to its own parser
      CLEANUP: cfgparse-global: move the process-wide limits to a single parser
      CLEANUP: cfgparse-global: move the compression limits to a single parser
      CLEANUP: cfgparse-global: move "ssl-server-verify" to its own parser
      CLEANUP: cfgparse-global: move "node" and "description" to their own 
parser
      CLEANUP: cfgparse-global: move "unix-bind" to its own parser
      CLEANUP: cfgparse-global: move the log keywords to a single parser
      CLEANUP: cfgparse-global: move the state file keywords to their own parser
      CLEANUP: cfgparse-global: move the spread-checks keywords to their own 
parser
      CLEANUP: cfgparse-global: move "cpu-map" to its own parser
      CLEANUP: cfgparse-global: move "anonkey" to its own parser
      CLEANUP: cfgparse-global: ask not to add new keywords in common_kw_list[]
      CLEANUP: cfgparse-global: simplify cfg_parse_global()
      MINOR: cfgparse-listen: introduce proxy_parse_removed_kw() and use it
      MEDIUM: cfgparse-listen: move removed keywords' help messages into an 
array
      CLEANUP: cfgparse-listen: move "disabled" and "enabled" to their own 
parser
      CLEANUP: cfgparse-listen: move the connection limits to thier own parser
      CLEANUP: cfgparse-listen: move the backend one-arg keywords to their own 
parser
      CLEANUP: cfgparse-listen: move "mode" to its own parser
      CLEANUP: cfgparse-listen: move "id" and "description" to their own parser
      CLEANUP: cfgparse-listen: move "acl" to its own parser
      CLEANUP: cfgparse-listen: move the monitor keywords to their own parser
      CLEANUP: cfgparse-listen: move the persistence keywords to their own 
parser
      CLEANUP: cfgparse-listen: move "capture" to its own parser
      CLEANUP: cfgparse-listen: move the log format keywords to their own parser
      CLEANUP: cfgparse-listen: add parser for "log", "log-tag" and 
"unique-id-header"
      CLEANUP: cfgparse-listen: move the load-balancing keywords to their own 
parser
      CLEANUP: cfgparse-listen: move "source" "usesrc" and "interface" to their 
own parser
      CLEANUP: cfgparse-listen: add parser for server/backend sekection keywords
      CLEANUP: cfgparse-listen: move the HTTP rule sets to their own parser
      CLEANUP: cfgparse-listen: move "redirect" to its own parser
      CLEANUP: cfgparse-listen: move "stick-table" to its own parser
      CLEANUP: cfgparse-listen: move "stick" to its own parser
      CLEANUP: cfgparse-listen: move "cookie" to its own parser
      CLENAUP: cfgparse-listen: move "email-alert" to its own parser
      CLEANUP: cfgparse-listen: move "stats" to its own parser
      CLENAUP: cfgparse-listen: move the "server" keywords to their own parser
      CLEANUP: cfgparse-listen: move "bind" to its own parser
      MINOR: log: add proxy_logformat_origin() to detect a proxy's log-format 
type
      CLEANUP: cfgparse-listen: move "option" to its own parser
      CLEANUP: cfgparse-listen: simplify the second half of cfg_parse_listen()
      MINOR: cfgparse: always suggest the section names on an unknown keyword
      CLEANUP: cfgparse: remove the unused common_kw_list[] definitions
      BUG/MEDIUM: mux-h2: don't return a freed tasklet from h2_deferred_shut()
      BUG/MEDIUM: mux-fcgi: don't return a freed tasklet from 
fcgi_deferred_shut()
      BUG/MEDIUM: mux-h1: don't pass an upgraded connection to traces in 
h1s_destroy()
      BUG/MEDIUM: mux-h2: report a dead rhttp connection in h2_wake()
      BUG/MEDIUM: mux-h2: fix a possible crash on rxbuf allocation failure
      BUG/MAJOR: mux-h2: properly handle short reads on PING frames

Yeonggi Kim (4):
      BUG/MEDIUM: cli: fix the last command detection on a full command line
      REGTESTS: cli: test a command line of exactly tune.bufsize bytes
      BUG/MEDIUM: log: do not ignore the peer's shutdown in the syslog applet
      REGTESTS: log: check that a log-forward TCP session ends on client close

---


Reply via email to