FlowiseAI/Flowise · error · Error

Invalid headers: too many entries (max ${MAX_HEADERS})

Error message

Invalid headers: too many entries (max ${MAX_HEADERS})

What it means

Enforces the MAX_HEADERS (25) cap to bound outbound request size and iteration cost. Throws when Object.entries(headers).length > 25.

Source

Thrown at packages/components/src/headerValidation.ts:46

const MAX_HEADERS = 25
const MAX_KEY_LENGTH = 128
const MAX_VALUE_LENGTH = 2048

/**
 * Validates a set of user-supplied HTTP headers intended for outbound requests.
 * Rejects malformed keys, CRLF/control-char injection in values, hop-by-hop and
 * sensitive header names, and oversized payloads. Throws a plain Error; callers
 * are responsible for mapping to their own error types.
 */
export function validateCustomHeaders(headers: Record<string, string>): void {
    if (!headers || typeof headers !== 'object') {
        throw new Error('Invalid headers: expected an object')
    }

    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`)
        }

View on GitHub (pinned to abe4a8601a)

Solutions

  1. Trim the header set to <=25 entries, keeping only the headers the downstream actually needs.
  2. Filter out hop-by-hop, denied, and sensitive headers BEFORE counting toward the cap.
  3. If you genuinely need more, raise MAX_HEADERS in the source (it is a module-level const) and document why.

Example fix

// before
validateCustomHeaders({ ...allInboundHeaders }) // 40 entries -> throws

// after
const allowlisted = pick(allInboundHeaders, ['accept', 'content-type', 'trace-id'])
validateCustomHeaders(allowlisted)
Defensive patterns

Strategy: validation

Validate before calling

// Enforce the cap before calling validateCustomHeaders
const MAX_HEADERS = 25
function trimToMax(headers, max = MAX_HEADERS) {
    const entries = Object.entries(headers)
    if (entries.length <= max) return headers
    return Object.fromEntries(entries.slice(0, max))
}

Type guard

function withinHeaderLimit(headers, max = 25) {
    return Object.keys(headers).length <= max
}

Try / catch

try {
    validateCustomHeaders(headers)
} catch (e) {
    if (/too many entries/i.test(e.message)) headers = trimToMax(headers)
    else throw e
    validateCustomHeaders(headers)
}

Prevention

When it happens

Trigger: Caller supplies a header bag with more than 25 entries.

Common situations: Forwarding the full inbound request header bag downstream (including cookies, forwarded chains, sec-* headers) without filtering; bulk custom-header injection exceeding the cap; concatenating multiple header sources.

Related errors


AI-assisted analysis of FlowiseAI/Flowise@abe4a8601a (2026-08-12). Data as JSON: /api/errors/9705cafe4088571e. Report an issue: GitHub.