maxuru ~ % cat haproxy/removed-directives
HAProxy reqadd, rspadd and reqirep were removed
/etc/haproxy/haproxy.cfg# Old (removed in 2.1 — will not start)# rspadd X-Frame-Options:\ DENY# reqideny ^User-Agent:.*sqlmap## Current http-response set-header X-Frame-Options DENY http-request deny if { req.hdr(user-agent) -m sub sqlmap }This page exists because the failure is loud but the advice is quiet: the config won’t start, the operator deletes the offending line to get the service back, and the control it was implementing quietly disappears with it.
What happened
Section titled “What happened”Before 2.1, HAProxy manipulated HTTP headers with a family of regex directives
operating on raw header lines: reqadd, reqrep, reqdel, reqdeny,
reqallow, reqtarpit, their case-insensitive reqi* twins, and the rsp*
equivalents for responses.
HAProxy 2.1 removed all of them. Not deprecated with a warning — removed, as a fatal parse error that names the replacement. The reason is the HTX engine: HAProxy now parses HTTP into a structured internal representation shared by HTTP/1, HTTP/2 and HTTP/3, and rules that ran a regex over a raw header line no longer have a raw header line to run over.
This matters for hardening specifically because rspadd was the documented way
to add security headers for about a decade, and reqideny was how guides
blocked scanners and bad user agents. A large fraction of HAProxy hardening
material written before 2020 is now a config that does not boot.
The translation table
Section titled “The translation table”| Removed | Use instead |
|---|---|
reqadd |
http-request add-header |
reqrep / cliexp |
http-request replace-path, replace-uri or replace-header |
reqirep |
http-request replace-header |
reqdel / reqidel |
http-request del-header |
reqdeny / reqideny |
http-request deny |
reqallow / reqiallow |
http-request allow |
reqtarpit / reqitarpit |
http-request tarpit |
reqpass / reqipass |
(no replacement — it did nothing but stop rule processing) |
rspadd |
http-response add-header |
rsprep / rspirep |
http-response replace-header |
rspdel / rspidel |
http-response del-header |
rspdeny / rspideny |
http-response deny |
HAProxy prints the right-hand column in the error itself, which makes the
translation mechanical. The one worth pausing on is add-header versus
set-header: add-header appends another copy of the header even if one is
already present, while set-header replaces any existing value. For security
headers you almost always want set-header, because two conflicting
X-Frame-Options headers is a worse outcome than either one alone — and the
literal replacement HAProxy suggests for rspadd is add-header.
Two related deprecations
Section titled “Two related deprecations”Not removals, but they show up in the same old configs:
option httpcloseand the long-goneoption forceclose— connection handling was reworked;option http-server-closeor the default keep-alive behaviour is what you want now.option accept-invalid-http-requestwas renamed tooption accept-unsafe-violations-in-http-request(and the response equivalent likewise). The rename is deliberate: the old name sounded like a compatibility toggle, and the new one says what it is. It relaxes HTTP parsing strictness, which is directly relevant to request smuggling — leave it off unless you have a specific broken client and understand what you are accepting.
Related
Section titled “Related”- Add security headers in HAProxy — what
rspaddwas usually doing. - Request smuggling — why parsing strictness options matter.