{"record":{"id":"47d69d8e792d3701","repo":"FlowiseAI/Flowise","slug":"invalid-header-key-key-contains-illegal-char","errorCode":null,"errorMessage":"Invalid header \"${key}\": key contains illegal characters","messagePattern":"Invalid header \"(.+?)\": key contains illegal characters","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/components/src/headerValidation.ts","lineNumber":57,"sourceCode":"export function validateCustomHeaders(headers: Record<string, string>): void {\n    if (!headers || typeof headers !== 'object') {\n        throw new Error('Invalid headers: expected an object')\n    }\n\n    const entries = Object.entries(headers)\n    if (entries.length > MAX_HEADERS) {\n        throw new Error(`Invalid headers: too many entries (max ${MAX_HEADERS})`)\n    }\n\n    for (const [key, value] of entries) {\n        if (typeof key !== 'string' || key.length === 0) {\n            throw new Error('Invalid header: key must be a non-empty string')\n        }\n        if (key.length > MAX_KEY_LENGTH) {\n            throw new Error(`Invalid header \"${key}\": key exceeds ${MAX_KEY_LENGTH} chars`)\n        }\n        if (!RFC7230_TOKEN.test(key)) {\n            throw new Error(`Invalid header \"${key}\": key contains illegal characters`)\n        }\n\n        const lower = key.toLowerCase()\n        if (DENIED_HEADER_NAMES.has(lower) || DENIED_HEADER_PREFIXES.some((p) => lower.startsWith(p))) {\n            throw new Error(`Invalid header \"${key}\": this header name is not allowed`)\n        }\n\n        if (typeof value !== 'string') {\n            throw new Error(`Invalid header \"${key}\": value must be a string`)\n        }\n        if (value.length > MAX_VALUE_LENGTH) {\n            throw new Error(`Invalid header \"${key}\": value exceeds ${MAX_VALUE_LENGTH} chars`)\n        }\n        for (let i = 0; i < value.length; i++) {\n            const code = value.charCodeAt(i)\n            if (code === 0x0d || code === 0x0a || (code < 0x20 && code !== 0x09)) {\n                throw new Error(`Invalid header \"${key}\": value contains illegal control characters`)\n            }","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/FlowiseAI/Flowise/blob/abe4a8601a058047b350c260676826e21dd14101/packages/components/src/headerValidation.ts#L39-L75","documentation":"Per-entry guard: each key must match RFC7230_TOKEN `/^[A-Za-z0-9!#$%&'*+\\-.^_`|~]+$/`. Any character outside that set fails — colon, space, slash, equals, parens, non-ASCII, etc.","triggerScenarios":"Header name contains a colon (e.g. 'Content-Type: text/plain' used as the name), a space, a slash, an equals sign, a trailing/leading space or newline, or any non-ASCII (UTF-8) character.","commonSituations":"User pasted 'Key: Value' into the key field; copy included a trailing space or newline; experimental Unicode header name; name includes a parenthetical or other punctuation.","solutions":["Use the bare header name without colon or value (e.g. 'Content-Type').","Trim whitespace from keys before submitting.","Restrict to RFC 7230 token characters: alphanumerics and !#$%&'*+-.^_`|~."],"exampleFix":"// before\nvalidateCustomHeaders({ 'Content-Type: application/json': '' }) // throws\nvalidateCustomHeaders({ ' X-Custom ': 'v' }) // throws (spaces)\n\n// after\nvalidateCustomHeaders({ 'Content-Type': 'application/json' })\nvalidateCustomHeaders({ 'X-Custom': 'v' })","handlingStrategy":"validation","validationCode":"// Reject non-token keys before validation\nconst RFC7230_TOKEN = /^[A-Za-z0-9!#$%&'*+\\-.^_`|~]+$/\nfunction onlyTokenKeys(headers) {\n    return Object.fromEntries(Object.entries(headers).filter(([k]) => RFC7230_TOKEN.test(k)))\n}","typeGuard":"function keysAreRfc7230Tokens(headers) {\n    const re = /^[A-Za-z0-9!#$%&'*+\\-.^_`|~]+$/\n    return Object.keys(headers).every((k) => re.test(k))\n}","tryCatchPattern":"try {\n    validateCustomHeaders(headers)\n} catch (e) {\n    if (/illegal characters/i.test(e.message)) {\n        // strip colon/value and trim, then retry\n        headers = Object.fromEntries(Object.entries(headers).map(([k, v]) => [k.trim().split(':')[0].trim(), v]))\n    } else throw e\n    validateCustomHeaders(headers)\n}","preventionTips":["Accept header names in a separate field from values at the UI; never let users type 'Name: Value' in one box.","Trim whitespace from header names before submission.","Reject non-ASCII header names at the form boundary."],"tags":["headers","validation","rfc7230","http"],"backgroundTag":null,"analyzedSha":"abe4a8601a058047b350c260676826e21dd14101","analyzedAt":"2026-08-12T16:04:40.823Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}