Hi, HAProxy 3.1.8 was released on 2025/05/28. It added 70 new commits after version 3.1.7.
As usual, this release fixed a bunch of bugs. Here is the list of issues that were fixed: * In the cache, when reference counters were added on cache entries, a regression was introduced that could lead to crash the process. When too many secondary entries were found in the cache for a given key, the wrong entry was released, corrupting the cache tree. To hit the bug, the processing of the "Vary" header must be enabled. The 3.0 is also affected by this bug. * Since we made it possible for a bind_conf to listen to multiple thread groups with shards in 2.8, the per-listener connection count was not properly transferred to the target listener with the connection when switching to another thread group. This resulted in one listener possibly reaching high values and another one possibly reaching negative values. Usually it was not visible, unless a maxconn was set on the bind_conf, in which case comparisons would quickly put an end to the willingness to accept new connections. This problem only happened when thread groups were enabled. * A regression was introduced in 3.1.7 about the watchdog. The first watchdog wakeup was no longer ignored, as before, and led to trigger a panic instead of giving a second chance. * In Lua, the detection of shutdowns for TCP applets based on the new API was not properly handled. The applet could hang, waiting for more data, instead of leaving. Concretely, this bug can only be hit by lua CLI commands. In addition, AppletTCP:getline() function was fixed to be able to handle the new applet API. Using it from a lua CLI command would lead to unexpected behavior. Finally, Channel:data() and Channel:line() functions was fixed to respect the documentation. * Several issues on the SPOP multiplexer were fixed. The negotiated "max-frame-size" parameter was not properly respected when frames were sent to the agent. A SPOP connection could be considered as ready before the end of the hello handshake and could be reused too early. SPOP Frames parsing did not handle properly the CLOSING state and did not wait for DISCONNECT frames from the agent as expected. Finally, truncated frames was not always detected and connection error could lead to skip the last frame received. * On peers, high latencies or even watchdog panics could be experienced during reloads because the full learning process sent a lot of data. While it can usually be OK with default settings, it could be an issue for setups involving a large tune.bufsize (1MB and above). There is a configurable limit to the number of messages sent to a peer (tune.peers.max-updates-at-once), but this one was not applied to the receive side. The issue was fixed by respecting this limit on receiving side too. In addition, segfaults could be experienced because of a tiny race condition where a stick-table entry was removed while its expiration timer was updated. * A crash could be experienced if a server was inserted via the "add server" command with an already existing GUID. * The 0-copy data forwarding was not disabled for filters altering the data. It could be an issue if the filter did not remain attached on the stream. Concretely, it could only be an issue for some LUA filters. * Several QUIC issues were fixed. A BUG_ON() on CRYPTO ncbuf allocation failures was replaced by a cleaner way to handle them and avoid to crash. The parsing of transport parameters was not fully aligned with the RFC 9000. Wrong error codes were used to missing or invalid transport parameter. Some others were not rejected. Long lived connections could consume unnecessary memory (but with no leak) because the stream descriptor content of acked data was not freed. Finally, minimum and maximum limits enforced on the congestion window were not always respected. * On H3, multiple Host headers were still preserved, only the values were compared. We are now aligned with the h1 and h2 by dropping extraneous headers. Information about :scheme pseudo-header were not properly reported at the HTX level, preventing the H2 multiplexer to preserve it on server side. * On the CLI, no error was reported when too many arguments were passed for a command. Instead, arguments above the limit (64 by default) were just silently ignored. * On the DNS part, an unexpected CPU usage could be experienced because there was no delay on connection retries. It was observed with a nameserver with invalid network settings. There is now a one-second delay between two connections. Related to this issue, it was also possible to have an accumulation of DNS sessions. The number of DNS sessions is now tracked When we reach a threshold (set to 100), we consider that the link to the dns server is broken (at least temporarily) and we stop creating new sessions until one of the existing one eventually succeeds. * On SSL, the crt-store keywords parsing was improved to avoid leak during configuration parsing when several occurrences of the same keyword were found. * The soft-stop was broken since a while when the thread support was disabled. Few improvements were also brought: * "send-proxy" and "send-proxy-v2" options are not relevant nor supported on a ring server. It is now explicitly ignored and a warning is emitted. * The API for the lua HTTPMessage "class" was improved to be able to change the body length. It was mandatory to be able to write a lua filter altering the message payload. HTTPMessage:set_body_len() can now be used for this purpose. * Still in lua, The HTTP client is not supposed to be used to process several requests but there was nothing to prevent this usage. An error is now triggered in that case and the lua documentation was updated to be clear on this point. * The number of old entries removed from a stick-table is now limited for one call to avoid high contention on the lock. The purge of old entries is thus executed more smoothly and this helps getting stick tables to perform better under heavy load. * The CI now relies on vtest2 which finally contains the fixes we were relying on and which is going to evolve. Thanks everyone for your help ! 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 Sources : https://www.haproxy.org/download/3.1/src/ Git repository : https://git.haproxy.org/git/haproxy-3.1.git/ Git Web browsing : https://git.haproxy.org/?p=haproxy-3.1.git Changelog : https://www.haproxy.org/download/3.1/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 --- Complete changelog : Amaury Denoyelle (14): BUG/MINOR: quic: do not crash on CRYPTO ncbuf alloc failure MINOR: quic: rename min/max fields for congestion window algo MINOR: quic: extend return value during TP parsing BUG/MINOR: quic: use proper error code on missing CID in TPs BUG/MINOR: quic: use proper error code on invalid server TP BUG/MINOR: quic: reject retry_source_cid TP on server side BUG/MINOR: quic: use proper error code on invalid received TP value BUG/MINOR: quic: fix TP reject on invalid max-ack-delay BUG/MINOR: quic: reject invalid max_udp_payload size BUG/MEDIUM: quic: free stream_desc on all data acked BUG/MINOR: mux-quic: do not decode if conn in error MINOR: quic: refactor BBR API BUG/MINOR: quic: ensure cwnd limits are always enforced BUG/MEDIUM: server: fix crash after duplicate GUID insertion Aurelien DARRAGON (9): MINOR: applet: add appctx_schedule() macro CLEANUP: dns: remove unused dns_stream_server struct member BUG/MINOR: dns: add tempo between 2 connection attempts for dns servers BUG/MINOR: dns: prevent ds accumulation within dss BUG/MINOR: proxy: only use proxy_inc_fe_cum_sess_ver_ctr() with frontends BUG/MINOR: cli: fix too many args detection for commands BUG/MINOR: threads: fix soft-stop without multithreading support BUG/MINOR: sink: detect and warn when using "send-proxy" options with ring servers DOC: config: restore default values for resolvers hold directive Basha Mougamadou (1): DOC: configuration: explicit multi-choice on bind shards option Christopher Faulet (29): BUG/MINOR: cli: Issue an error when too many args are passed for a command BUG/MINOR: mux-h1: Don't pretend connection was released for TCP>H1>H2 upgrade BUG/MINOR: mux-h1: Fix trace message in h1_detroy() to not relay on connection BUG/MINOR: hlua: Fix Channel:data() and Channel:line() to respect documentation BUG/MINOR: spoe: Don't report error on applet release if filter is in DONE state BUG/MEDIUM: mux-spop: Respect the negociated max-frame-size value to send frames BUG/MEDIUM: mux-spop: Wait end of handshake to declare a spop connection ready BUG/MINOR: mux-spop: Use the right bitwise operator in spop_ctl() BUG/MINOR: mux-spop: Don't report error for stream if ACK was already received BUG/MINOR: mux-spop: Make the demux stream ID a signed integer BUG/MINOR: mux-spop: Don't open new streams for SPOP connection on error MINOR: mux-spop: Don't set SPOP connection state to FRAME_H after ACK parsing BUG/MEDIUM: mux-spop: Remove frame parsing states from the SPOP connection state BUG/MEDIUM: mux-spop: Properly handle CLOSING state BUG/MEDIUM: spop-conn: Report short read for partial frames payload BUG/MEDIUM: mux-spop; Don't report a read error if there are pending data DEBUG: mux-spop: Review some trace messages to adjust the message or the level BUG/MEDIUM: mux-spop: Properly detect truncated frames on demux to report error MEDIUM: hlua: Add function to change the body length of an HTTP Message BUG/MEDIUM: stconn: Disable 0-copy forwarding for filters altering the payload BUG/MINOR: h3: Set HTX flags corresponding to the scheme found in the request BUG/MEDIUM: hlua: Properly detect shudowns for TCP applets based on the new API BUG/MEDIUM: hlua: Fix getline() for TCP applets to work with applet's buffers REGTESTS: Make the script testing conditional set-var compatible with Vtest2 REGTESTS: Explicitly allow failing shell commands in some scripts CI: vtest: Rely on VTest2 to run regression tests CI: vtest: Fix the build script to properly work on MaOS BUG/MEDIUM: httpclient: Throw an error if an lua httpclient instance is reused DOC: hlua: Add a note to warn user about httpclient object reuse Frederic Lecaille (2): CLEANUP: quic: Useless BIO_METHOD initialization MINOR: quic: Add useful error traces about qc_ssl_sess_init() failures Lukas Tribus (1): DOC: ring: refer to newer RFC5424 Olivier Houchard (2): BUG/MEDIUM: connections: Report connection closing in conn_create_mux() MEDIUM: stick-tables: Limit the number of old entries we remove Remi Tricot-Le Breton (1): BUG/MAJOR: cache: Crash because of wrong cache entry deleted William Lallemand (2): BUG/MINOR: ssl/ckch: always free() the previous entry during parsing DOC: configuration: fix the example in crt-store Willy Tarreau (9): BUG/MAJOR: listeners: transfer connection accounting when switching listeners BUG/MEDIUM: peers: hold the refcnt until updating ts->seen BUG/MEDIUM: peers: also limit the number of incoming updates DOC: config: recommend disabling libc-based resolution with resolvers BUG/MINOR: h3: don't insert more than one Host header BUILD: debug: mark ha_crash_now() as attribute(noreturn) BUG/MEDIUM: wdt: always ignore the first watchdog wakeup BUG/MEDIUM: server: fix potential null-deref after previous fix DOC: hlua: fix a few typos in HTTPMessage.set_body_len() documentation -- Christopher Faulet