FlowiseAI/Flowise · error · Error
Invalid header "${key}": this header name is not allowed
Error message
Invalid header "${key}": this header name is not allowed What it means
Deny-list enforcement. DENIED_HEADER_NAMES = {host, content-length, transfer-encoding, connection, upgrade, cookie, set-cookie, proxy-authorization, proxy-connection}. DENIED_HEADER_PREFIXES = ['proxy-', 'x-forwarded-', 'sec-']. These are hop-by-hop (RFC 7230 §6.1), routing/injection, or cookie headers that the system reserves or forbids for outbound requests. Comparison is case-insensitive on the lowercased key.
Source
Thrown at packages/components/src/headerValidation.ts:62
const entries = Object.entries(headers)
if (entries.length > MAX_HEADERS) {
throw new Error(`Invalid headers: too many entries (max ${MAX_HEADERS})`)
}
for (const [key, value] of entries) {
if (typeof key !== 'string' || key.length === 0) {
throw new Error('Invalid header: key must be a non-empty string')
}
if (key.length > MAX_KEY_LENGTH) {
throw new Error(`Invalid header "${key}": key exceeds ${MAX_KEY_LENGTH} chars`)
}
if (!RFC7230_TOKEN.test(key)) {
throw new Error(`Invalid header "${key}": key contains illegal characters`)
}
const lower = key.toLowerCase()
if (DENIED_HEADER_NAMES.has(lower) || DENIED_HEADER_PREFIXES.some((p) => lower.startsWith(p))) {
throw new Error(`Invalid header "${key}": this header name is not allowed`)
}
if (typeof value !== 'string') {
throw new Error(`Invalid header "${key}": value must be a string`)
}
if (value.length > MAX_VALUE_LENGTH) {
throw new Error(`Invalid header "${key}": value exceeds ${MAX_VALUE_LENGTH} chars`)
}
for (let i = 0; i < value.length; i++) {
const code = value.charCodeAt(i)
if (code === 0x0d || code === 0x0a || (code < 0x20 && code !== 0x09)) {
throw new Error(`Invalid header "${key}": value contains illegal control characters`)
}
}
}
}
/**View on GitHub (pinned to abe4a8601a)
Solutions
- Remove the denied header from the set; let the HTTP client set Host, Connection, Content-Length, Transfer-Encoding itself.
- For authentication use 'Authorization' (not denied) instead of Cookie / Proxy-Authorization.
- Strip 'X-Forwarded-*', 'Sec-*', and 'Proxy-*' from inbound headers before forwarding.
Example fix
// before
validateCustomHeaders({
Host: 'example.com',
'X-Forwarded-For': '1.2.3.4',
Cookie: 'session=...'
}) // all three throw
// after
validateCustomHeaders({
Authorization: 'Bearer ...',
'X-Trace-Id': 'abc'
}) Defensive patterns
Strategy: validation
Validate before calling
// Strip denied hop-by-hop / routing / cookie headers before validation
const DENIED = new Set(['host','content-length','transfer-encoding','connection','upgrade','cookie','set-cookie','proxy-authorization','proxy-connection'])
const DENIED_PREFIX = ['proxy-','x-forwarded-','sec-']
function stripDenied(headers) {
const out = {}
for (const [k, v] of Object.entries(headers)) {
const lower = k.toLowerCase()
if (DENIED.has(lower) || DENIED_PREFIX.some((p) => lower.startsWith(p))) continue
out[k] = v
}
return out
} Type guard
function hasNoDeniedHeaders(headers) {
const denied = new Set(['host','content-length','transfer-encoding','connection','upgrade','cookie','set-cookie','proxy-authorization','proxy-connection'])
return Object.keys(headers).every((k) => {
const lower = k.toLowerCase()
return !denied.has(lower) && !['proxy-','x-forwarded-','sec-'].some((p) => lower.startsWith(p))
})
} Try / catch
try {
validateCustomHeaders(headers)
} catch (e) {
if (/header name is not allowed/i.test(e.message)) headers = stripDenied(headers)
else throw e
validateCustomHeaders(headers)
} Prevention
- Let the HTTP client set Host, Connection, Content-Length, Transfer-Encoding itself.
- Use 'Authorization' for credentials, never Cookie or Proxy-Authorization.
- Strip 'X-Forwarded-*', 'Sec-*', and 'Proxy-*' from inbound headers before forwarding downstream.
When it happens
Trigger: Caller includes any exact denied name (e.g. 'Host', 'Connection', 'Cookie') or any name whose lowercase form starts with 'proxy-', 'x-forwarded-', or 'sec-' (e.g. 'X-Forwarded-For', 'Sec-Fetch-Mode', 'Proxy-Connection').
Common situations: Forwarding the full inbound header bag downstream without stripping hop-by-hop/routing headers; trying to set Host manually; passing auth via Cookie or Proxy-Authorization instead of Authorization; security/browser headers (Sec-*) carried over from an inbound browser request.
Related errors
- Invalid header "${key}": value contains illegal control char
- Invalid headers: expected an object
- Invalid headers: too many entries (max ${MAX_HEADERS})
- Invalid header: key must be a non-empty string
- Invalid header "${key}": key exceeds ${MAX_KEY_LENGTH} chars
AI-assisted analysis of FlowiseAI/Flowise@abe4a8601a (2026-08-12).
Data as JSON: /api/errors/d7753d4e5e134f2e.
Report an issue: GitHub.