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
- Sanitize or reject the incoming Accept-Language header before passing it to acceptLanguage().
- Identify the client/proxy producing the malformed header and fix it at the source.
- 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
- Always wrap acceptLanguage() in try/catch with a fallback locale.
- Sanitize incoming Accept-Language before parsing.
- Log malformed headers to identify misbehaving clients/proxies.
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
- `after()`: Argument must be a promise or a function
- `after()` will not work correctly, because `waitUntil` is no
- `after` was called outside a request scope. Read more: https
- Invalid redirect arguments. Please use a single argument URL
- Preview data is limited to 2KB currently, reduce how much da
AI-assisted analysis of vercel/next.js@0ae8c72462 (2026-08-06).
Data as JSON: /api/errors/4d37e9221bd0bf4c.
Report an issue: GitHub.