Release notes
HAProxy Data Plane API 3.4 release notes
The HAProxy Data Plane API 3.4 release rewrites the API server from go-swagger to a chi router with oapi-codegen generated handlers (OpenAPI 3) and adds full configuration support for HAProxy 3.4. Endpoint paths, methods, parameters and success responses are unchanged, but a small number of client-visible behavior changes are described below.
This release supports HAProxy 3.4 and newer versions.
New features Jump to heading
New features in this release include the following:
-
Added support for the
force-be-switchfrontend directive, with a registered handler and parser/configuration support. -
Added full CRUD support for the HAProxy
healthchecksection, including handlers andoapi-codegenspecification and configuration, parser and specification support. -
Added HAProxy 3.4 proxy options:
option use-small-buffers(defaults, listen, backend) with optional queue, l7-retries and check modes; andstats show-version(defaults, frontend, listen, backend) for the stats page. -
Added HAProxy 3.4 global process options:
cpu-affinity,max-threads-per-group, andstats calculate-max-counters. -
Added HAProxy 3.4 global tunable options:
tune.bufsize.large,tune.cli.max-payload-size,tune.h2.be.max-frames-at-once,tune.h2.fe.max-frames-at-once,tune.h2.fe.max-rst-at-once,tune.h2.log-errors,tune.lua.openlibs,tune.quic.fe.stream.max-total,tune.defaults.purge,tune.h1.be.glitches-threshold,tune.h1.fe.glitches-threshold, andtune.ssl.certificate-compression. -
Added the HTTP actions
add-headers-bin,del-headers-bin, andset-headers-bin. -
Added the
filter-sequencedirective andcomp-req/comp-resfilters. -
Extended
set-timeout,do-logandfilter tracefor HAProxy 3.4. -
Added the
quic-cc-algoserver directive. -
Added the
shardsandtcp-ssbind options. -
Added the
fd-hard-limitglobal option. -
Allowed HAProxy variables in the format
${VAR}in peer entries, nameservers, mailer entries, userlist groups/users, and frontendlog_tag. -
Removed the deprecated
req_ssl_sni, replaced byreq.ssl_sni. -
Extended ACME support:
- Added support for the
dns-persist-01ACME challenge. - Added the
profileACME keyword. - Added new ACME keywords for HAProxy 3.4:
challenge-ready,dns-delay, anddns-timeout. - Allowed setting the DNS TTL via
acme-vars.
For a tutorial, see Enable TLS by using the ACME protocol.
- Added support for the
-
Updated runtime behavior:
- Added all supported server parameters to the runtime server handler.
- Added all fields for the runtime server, added server
weightand made the address editable. - Improved HAProxy runtime version checks and allowed
ExecuteRawto run multiple commands at once.
-
Updated server and request handling:
- Added a configurable request body size limit via
--max-body-size(default 1 GiB). - Stream multipart uploads instead of buffering them in memory.
- Exposed the client-native
validate_files_afterandvalidate_files_beforeoptions.
- Added a configurable request body size limit via
Major changes Jump to heading
Major changes in this release include the following:
-
Replaced the
go-swaggergeneratedDataPlaneAPIserver with a chi router andoapi-codegengenerated handlers (OpenAPI 3). Where chi’s defaults differ from the old server, the router carries explicit code to keep the wire behavior unchanged:- JSON bodies for router-level errors: chi answers unmatched paths and disallowed methods with plain-text bodies (
404 page not found); custom handlers restore the JSON shape the go-swagger server returned ({"code": 404, "message": "path ... was not found"}). They are registered on both the root router and the mounted/v3sub-router. - The
Allowheader on 405 responses: RFC 9110 requires a 405 response to list the methods the resource supports, and the go-swagger server did so; chi does not expose the matched route’s allowed methods to a custom 405 handler, so the handler rebuilds the list by probing the router with each standard method for the requested path. - Trailing slashes are ignored: Requests are routed as if a trailing slash were absent (chi’s
StripSlashesmiddleware), so/v3/.../mapsand/v3/.../maps/hit the same handler. Reload-IDheader spelling: The specification spells the reload headerReload-ID, while the server sends the canonicalReload-Idform — exactly as the old go-swagger server did, since Go’shttp.Headercanonicalizes header names on write. Header names are case-insensitive, so clients should treat the two spellings as equal.
- JSON bodies for router-level errors: chi answers unmatched paths and disallowed methods with plain-text bodies (
-
Migrated all handlers to
oapi-codegenand moved the path specification out of client-native into dataplaneapi, with new specification-generation tooling. -
Removed the now unused
operationsfolder and deprecated generation code.
Bug fixes Jump to heading
This release includes the following bug fixes:
- Trigger a reload when replacing an
http-errorssection. - Fixed data races, a goroutine leak and reconnect logic in the events listener.
- Fixed a nil-dereference panic in the events listener
Stop(). - ACME: fixed saving certificates into a
crt-store. - ACME: increased the default TTL to 1 minute.
- Fixed ACME DNS-01 propagation checks.
- Return the correct error code when adding duplicates into a map file.
- Ignore empty runtime API commands.
- Fixed crashes and non-idempotent serialization.
- Order the
fcgi-appsection before proxies. - Set the
log-profilemetadata comment on the right section. - Preserve quoting of
log-profilestep sd/format. - Fixed serialization of the ACME
provider-name. - Added
"to name regexes to support variable names. - Dropped the RSA-only bits minimum for ACME.
- Fixed read-only fields for the SSL certificate resource.
- Generate the specification with the proper template.
- Fixed a typo in specification description fields.
- Fixed
force-be-switchrule parsing and parts condition. crt_store: fixed the section to match the v3 URL structure.userlists: fixed ordering of users in serialization.dgram-bind: fixed IPv6 address parsing and serialization.server: don’t set the port to0when it isn’t set.- Fixed a typo and a boolean type in the runtime server.
raw: use the custom validation command on validate-only.- Ensure heredoc payloads have a blank-line terminator.
- Fixed a data race on
lastErrorcausing a nil-pointer panic. - Fixed an
EventListenerClose()deadlock and channel panic. - Reject special characters in file names.
- Get the real storage name of certificates.
Other Changes Jump to heading
Other changes in this release include the following.
Build and dependencies Jump to heading
- Upgraded Go to 1.26.
- Upgraded
golangci-lintand fixed the resulting linting errors. - Upgraded the client-native library to v6.4.0.
- Updated AWS SDK,
golang.org/x, go-openapi and gRPC packages. - Added specification-generation support and updated codegen dependencies.
- client-native: upgraded
go-method-gento v0.1.4 and handled interface types in the struct-equal generator.
Testing Jump to heading
- Migrated e2e fixtures to
log_targets. - Added e2e and unit tests for the
healthchecksection, the auth middleware, and the respond helpers. - Fixed stale endpoint paths and assertions; raw endpoints no longer send JSON; moved
crt-listtests to the proper URL. - Fixed a flaky SSL storage test and a syntax error in the e2e groups test.
CI/CD Jump to heading
- Require
pipelines-checkfor all jobs and added JUnit reporting. - Added
check-dependenciesandcheck-committerjobs. - Use the latest-alpine golang image; removed the
check-large-filesjob; bumped the commit-check version.
Breaking changes Jump to heading
This release introduces the following breaking changes:
-
Validation failures that previously carried
go-swaggerinternal codes in the body (e.g.{"code": 606}with HTTP 422) now return the HTTP status in the body ({"code": 422}). Clients matching on the old 6xx body codes must switch to the HTTP status. -
Raw configuration endpoints are text-only.
POST /services/haproxy/configuration/rawaccepts onlytext/plainbodies; the previous (accidental) JSON-encoded-string body is no longer accepted, and error responses are nowapplication/jsoninstead oftext/plain. -
Unmatched paths require authentication. Basic auth is enforced in front of the router, so an unauthenticated request to a non-existent path now returns
401instead of404. -
SSL certificate
DELETEcan return204.DELETE /services/haproxy/storage/ssl_certificates/{name}withoutskip_reload/force_reloadnow removes via the HAProxy Runtime API and returns204on success, falling back to202with aReload-IDheader. Treat both as success. -
Request bodies are capped at 1 GiB by default. Bodies exceeding the limit are rejected with
413. This is configurable via--max-body-size(max_body_size); A0value disables it. -
Replacing
acme,log_profiles,crt_stores,mailers_sectionandhttp_errors_sectionsnow triggers a reload. ThesePUTendpoints previously wrote the change without scheduling a reload; they now follow the standard pattern (202withReload-ID, or200withforce_reload=true). -
Removed deprecated process-manager (
program) endpoints, following the removal of theprogramsection from HAProxy. -
Removed unused cluster endpoints.
-
Removed deprecated
--log-*/--syslog-*CLI options and the persistedlogstorage section, superseded by thelog_targetsconfiguration. When no log targets are configured, the API defaults to astdouttarget.
Contributors Jump to heading
Thank you to those who contributed to HAProxy Data Plane API 3.4!
| Contributor | Area |
|---|---|
| AdamJCrawford | FEATURE |
| ahusic | FEATURE, BUILD, TEST |
| Andjelko Iharos | BUG |
| Dario Tranchitella | BUG |
| Dinko Korunic | BUG |
| Helene Durand | FEATURE |
| Ivan Matmati | FEATURE, BUILD |
| Marko Juraga | FEATURE, BUG, BUILD, CLEANUP, DOC, TEST |
| Olivier Duclos | FEATURE, BUG, BUILD, TEST |
| Pierre-Alain SIMON | FEATURE |
| Robert Maticevic | FEATURE, BUG, BUILD, CLEANUP, DOC, REORG, TEST |
| Zlatko Bratkovic | FEATURE, BUILD |