{"record":{"id":"f8a0ba45b612d00b","repo":"spring-projects/spring-security","slug":"the-request-was-rejected-because-the-header-name-f8a0ba","errorCode":null,"errorMessage":"The request was rejected because the header name \"<headerNames>\" is not allowed.","messagePattern":"The request was rejected because the header name \"<headerNames>\" is not allowed\\.","errorType":"exception","errorClass":"ServerExchangeRejectedException","httpStatus":400,"severity":"error","filePath":"web/src/main/java/org/springframework/security/web/server/firewall/StrictServerWebExchangeFirewall.java","lineNumber":635,"sourceCode":"\t\treturn result;\n\t}\n\n\tprivate boolean isNormalized(ServerHttpRequest request) {\n\t\tif (!isNormalized(request.getPath().value())) {\n\t\t\treturn false;\n\t\t}\n\t\tif (!isNormalized(request.getURI().getRawPath())) {\n\t\t\treturn false;\n\t\t}\n\t\tif (!isNormalized(request.getURI().getPath())) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\n\tprivate void validateAllowedHeaderName(String headerNames) {\n\t\tif (!StrictServerWebExchangeFirewall.this.allowedHeaderNames.test(headerNames)) {\n\t\t\tthrow new ServerExchangeRejectedException(\n\t\t\t\t\t\"The request was rejected because the header name \\\"\" + headerNames + \"\\\" is not allowed.\");\n\t\t}\n\t}\n\n\tprivate void validateAllowedHeaderValue(Object key, @Nullable String value) {\n\t\tif (!StrictServerWebExchangeFirewall.this.allowedHeaderValues.test(value)) {\n\t\t\tthrow new ServerExchangeRejectedException(\"The request was rejected because the header: \\\"\" + key\n\t\t\t\t\t+ \" \\\" has a value \\\"\" + value + \"\\\" that is not allowed.\");\n\t\t}\n\t}\n\n\tprivate void validateAllowedParameterName(String name) {\n\t\tif (!StrictServerWebExchangeFirewall.this.allowedParameterNames.test(name)) {\n\t\t\tthrow new ServerExchangeRejectedException(\n\t\t\t\t\t\"The request was rejected because the parameter name \\\"\" + name + \"\\\" is not allowed.\");\n\t\t}\n\t}\n","sourceCodeStart":617,"sourceCodeEnd":653,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/web/src/main/java/org/springframework/security/web/server/firewall/StrictServerWebExchangeFirewall.java#L617-L653","documentation":"The firewall validates every request header name against the allowedHeaderNames predicate. A header whose name fails the predicate is rejected with ServerExchangeRejectedException. This blocks header-injection attacks using malformed or illegal header names.","triggerScenarios":"A request carries a header whose name does not pass allowedHeaderNames — e.g. custom headers with invalid characters, headers containing non-ASCII or control characters, or a default predicate rejecting the name of a header a client/proxy adds.","commonSituations":"Clients sending unusual custom headers (X-Foo with weird casing/characters) during migration from a less strict setup; middleware adding headers the firewall's default predicate rejects; upgrading Spring Security where default header-name rules tightened; typo'd header names generated dynamically.","solutions":["Inspect the rejected header name in the logs and remove/fix it on the client that sends it.","If the header is legitimate, widen allowedHeaderNames via firewall.setAllowedHeaderNames(name -> name.matches(\"[a-zA-Z0-9-]+\")) or similar safe pattern.","Fix proxy/middleware config that injects malformed header names.","Encode the header name to valid HTTP token characters at the source."],"exampleFix":"// before\nStrictServerWebExchangeFirewall firewall = new StrictServerWebExchangeFirewall();\n// after: allow standard token header names plus a custom one\nfirewall.setAllowedHeaderNames(name ->\n    name.matches(\"[A-Za-z0-9-]+\") || name.equals(\"X-Custom-Id\"));","handlingStrategy":"validation","validationCode":"boolean isSafeHeaderName(String name) {\n    return name != null && name.matches(\"[A-Za-z0-9-]+\") && name.length() <= 128;\n}","typeGuard":null,"tryCatchPattern":"try {\n    exchange = firewall.getFirewalledExchange(exchange);\n} catch (ServerExchangeRejectedException e) {\n    log.warn(\"Rejected header name: {}\", e.getMessage());\n    return ResponseEntity.badRequest().build();\n}","preventionTips":["Only send standard HTTP token header names (letters, digits, hyphens).","Audit middleware/proxies for headers they inject.","Keep a documented allowlist of custom headers and test against the firewall config.","Never construct header names dynamically from user input."],"tags":["security","spring-security","http-headers","firewall"],"backgroundTag":"invalid-argument-format","analyzedSha":"96852e8860138a482cb13d1479573f24ff6443c6","analyzedAt":"2026-09-10T23:25:23.477Z","contentChangedAt":"2026-09-10T23:25:23.477Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}