angular/angular-cli · error · Error
Header "x-forwarded-prefix" is invalid. It must start with a
Error message
Header "x-forwarded-prefix" is invalid. It must start with a "/" and contain only alphanumeric characters, hyphens, and underscores, separated by single slashes.
What it means
Angular SSR checks the trusted `x-forwarded-prefix` header against `/^\/([a-z0-9_-]+\/)*[a-z0-9_-]*$/i`. The value must be a path prefix starting with `/`, containing only alphanumerics, hyphens, and underscores separated by single slashes. Anything else (full URLs, query strings, double slashes, spaces) is rejected to prevent prefix injection into generated asset/base href URLs.
Source
Thrown at packages/angular/ssr/src/utils/validation.ts:225
}
if (forwardedParams.proto && !VALID_PROTO_REGEX.test(forwardedParams.proto)) {
throw new Error('Header "forwarded" proto parameter must be either "http" or "https".');
}
}
const xForwardedPort = getFirstHeaderValue(headers.get('x-forwarded-port'));
if (xForwardedPort && !VALID_PORT_REGEX.test(xForwardedPort)) {
throw new Error('Header "x-forwarded-port" must be a numeric value.');
}
const xForwardedProto = getFirstHeaderValue(headers.get('x-forwarded-proto'));
if (xForwardedProto && !VALID_PROTO_REGEX.test(xForwardedProto)) {
throw new Error('Header "x-forwarded-proto" must be either "http" or "https".');
}
const xForwardedPrefix = getFirstHeaderValue(headers.get('x-forwarded-prefix'));
if (xForwardedPrefix && !VALID_PREFIX_REGEX.test(xForwardedPrefix)) {
throw new Error(
'Header "x-forwarded-prefix" is invalid. It must start with a "/" and contain ' +
'only alphanumeric characters, hyphens, and underscores, separated by single slashes.',
);
}
}
/**
* Checks if a specific proxy header is allowed.
*
* @param headerName - The name of the proxy header to check.
* @param trustProxyHeaders - A set of allowed proxy headers.
* @returns `true` if the header is allowed, `false` otherwise.
*/
export function isProxyHeaderAllowed(
headerName: string,
trustProxyHeaders: ReadonlySet<string>,
): boolean {
return (View on GitHub (pinned to bb72145f9a)
Solutions
- Configure the proxy to send only the path prefix, e.g. `/my-app`.
- Strip the scheme/host portion from the value at the proxy (use the path only).
- Remove `x-forwarded-prefix` from `trustProxyHeaders` if you don't rewrite asset paths.
- Fix double/trailing slashes: use `/app` or `/app/`-style paths matching the regex (single slashes between segments).
Example fix
// before proxy_set_header X-Forwarded-Prefix "https://cdn.example.com/app"; // after proxy_set_header X-Forwarded-Prefix "/app";
Defensive patterns
Strategy: validation
Validate before calling
const prefix = request.headers.get('x-forwarded-prefix')?.split(',')[0].trim();
if (prefix && !/^\/([a-z0-9_-]+\/)*[a-z0-9_-]*$/i.test(prefix)) throw new Error(`Invalid x-forwarded-prefix: ${prefix}`); Try / catch
try {
validateHeaders(headers, allowedHosts, disableHostCheck);
} catch (e) {
if ((e as Error).message.includes('x-forwarded-prefix')) {
return res.status(400).end('Invalid prefix header');
}
throw e;
} Prevention
- Send only path prefixes (starting with /), never full URLs.
- Normalize double/trailing slashes at the proxy.
- Only trust x-forwarded-prefix if you deploy under a subpath.
When it happens
Trigger: A request with a trusted `x-forwarded-prefix` header value like `https://x.com/app`, `my-prefix` (no leading slash), `//app`, `/app/`, trailing content with `?`, or an absolute URL.
Common situations: Proxies that set X-Forwarded-Prefix to a full URL instead of a path; platform-as-a-service routers appending the deployment path with extra characters; hand-crafted test requests.
Related errors
- Header "x-forwarded-port" must be a numeric value.
- Header "x-forwarded-proto" must be either "http" or "https".
- Header "${headerName}" with value "${headerValue}" is not al
- Header "forwarded" proto parameter must be either "http" or
- "${TRUST_ALL_PROXY_HEADERS}" is not allowed as a value for t
AI-assisted analysis of angular/angular-cli@bb72145f9a (2026-08-30).
Data as JSON: /api/errors/10dade87c43d931a.
Report an issue: GitHub.