verifyfirst

A status code · field-name-case-varies-with-the-version · documented

Field names arrive lowercased over HTTP/2, so a case-sensitive check passes vacuously

NS-079 documentedfield-name-case-varies-with-the-version

Field names arrive lowercased over HTTP/2, so a case-sensitive check passes vacuously

reads as
The audit greps the response headers for `^Set-Cookie:` lines lacking the Secure attribute, finds none, and records a pass. Conclusion drawn: no insecure cookie is being set.
actually
RFC 9113 requires that field names MUST be converted to lowercase when constructing an HTTP/2 message. Over HTTP/2 the field arrives as `set-cookie:` and a pattern anchored to `^Set-Cookie:` matches nothing at all, neither the compliant cookies nor the insecure ones. Which casing arrives is decided by the version negotiated for that particular request, which is a property of the connection rather than of the URL, so the same command can examine everything in one environment and nothing in the next.
blind because
An absence-based assertion cannot separate 'the condition does not occur' from 'the field was never examined'. Both return zero matches, exit the same way, and read as a clean result.
the check
Prove the pattern matches something before trusting that it matched nothing, and record the version alongside it: compare `curl -sD - -o /dev/null --http1.1 URL | grep -c '^Content-Type:'` against the same command with `--http2`. Observed at 00:28 UTC on 2026-08-24 against https://www.cloudflare.com/: 1 under --http1.1, 0 under --http2, and 1 under --http2 for `grep -c '^content-type:'`. `--http2` had also negotiated 1.1 without complaint against a local HTTP/1.1-only server, reporting `version=1.1 code=200` and exiting 0.
cost of missing
A control that has never once evaluated its subject reports a pass on every run, and the run history makes it look like a stable, long-standing green.
mitigation
Match case-insensitively, and give every absence-based check a positive control that must match for the check to be considered to have run.
generalises to
Every check whose passing condition is an empty result set: greps for a forbidden pattern, queries returning no rows, log searches finding no errors, linters with a misconfigured include path.
source
rfc-editor.org

Reported as

Others this instrument misses

plain text · full registry