vercel/next.js · error · Error

Invalid ${options.type} header

Error message

Invalid ${options.type} header

What it means

Thrown by the accept-header parser when a single comma-separated part of the Accept-Language header contains more than one semicolon parameter (params.length > 2). A valid token allows at most one q-parameter (e.g. 'en;q=0.8'); extra parameters like 'en;q=0.8;x=y' are invalid per the parsing grammar Next.js enforces.

Source

Thrown at packages/next/src/server/accept-header.ts:50

          }
        }
      }
    }
  }

  const parts = header.split(',')
  const selections: Selection[] = []
  const map = new Set<string>()

  for (let i = 0; i < parts.length; ++i) {
    const part = parts[i]
    if (!part) {
      continue
    }

    const params = part.split(';')
    if (params.length > 2) {
      throw new Error(`Invalid ${options.type} header`)
    }

    let token = params[0].toLowerCase()
    if (!token) {
      throw new Error(`Invalid ${options.type} header`)
    }

    const selection: Selection = { token, pos: i, q: 1 }
    if (preferences && lowers.has(token)) {
      selection.pref = lowers.get(token)!.pos
    }

    map.add(selection.token)

    if (params.length === 2) {
      const q = params[1]
      const [key, value] = q.split('=')

View on GitHub (pinned to 0ae8c72462)

Solutions

  1. Sanitize or reject the incoming Accept-Language header before passing it to acceptLanguage().
  2. Identify the client/proxy producing the malformed header and fix it at the source.
  3. Wrap the acceptLanguage() call in try/catch and fall back to a default locale.

Example fix

// before
const locale = acceptLanguage(req.headers['accept-language'], ['en', 'fr'])
// after - guard against malformed headers
function safeAcceptLanguage(header, prefs, fallback) {
  try { return acceptLanguage(header, prefs) || fallback }
  catch { return fallback }
}
const locale = safeAcceptLanguage(req.headers['accept-language'], ['en', 'fr'], 'en')
Defensive patterns

Strategy: try-catch

Validate before calling

function sanitizeAcceptLanguage(header: string): string {
  return header.split(',').map(seg => {
    const parts = seg.trim().split(';')
    if (parts.length > 2) return parts[0] + (parts[1] ? ';' + parts[1] : '')
    return seg.trim()
  }).join(',')
}

Try / catch

try {
  const locale = acceptLanguage(header, prefs)
} catch {
  locale = 'en' // fallback
}

Prevention

When it happens

Trigger: An Accept-Language header value where a segment has two or more ';' parameters, e.g. 'en;q=0.8;extra=1'. The split(';') yields 3+ elements, hitting the throw at line 50.

Common situations: A misbehaving client/proxy injecting extra parameters; manual header crafting in tests; a CDN rewriting headers. Real browsers do not produce this, so it usually indicates a malformed or tampered request.

Related errors


AI-assisted analysis of vercel/next.js@0ae8c72462 (2026-08-06). Data as JSON: /api/errors/4d37e9221bd0bf4c. Report an issue: GitHub.