{"record":{"id":"1402ba1f1aa42b88","repo":"angular/angular-cli","slug":"header-is-not-a-valid-proxy-header-trusted-p","errorCode":null,"errorMessage":"\"${header}\" is not a valid proxy header. Trusted proxy headers must be \"forwarded\" or start with \"x-forwarded-\".","messagePattern":"\"(.+?)\" is not a valid proxy header\\. Trusted proxy headers must be \"forwarded\" or start with \"x-forwarded-\"\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/angular/ssr/src/utils/validation.ts","lineNumber":275,"sourceCode":"  if (!trustProxyHeaders) {\n    return new Set();\n  }\n\n  if (trustProxyHeaders === true) {\n    return new Set([TRUST_ALL_PROXY_HEADERS]);\n  }\n\n  const normalizedTrustedProxyHeaders = new Set<string>();\n  for (const header of trustProxyHeaders) {\n    const lowerHeader = header.toLowerCase();\n    if (lowerHeader === TRUST_ALL_PROXY_HEADERS) {\n      throw new Error(\n        `\"${TRUST_ALL_PROXY_HEADERS}\" is not allowed as a value for the \"trustProxyHeaders\" option.`,\n      );\n    }\n    const isValid = lowerHeader === 'forwarded' || lowerHeader.startsWith('x-forwarded-');\n    if (!isValid) {\n      throw new Error(\n        `\"${header}\" is not a valid proxy header. Trusted proxy headers must be \"forwarded\" or start with \"x-forwarded-\".`,\n      );\n    }\n    normalizedTrustedProxyHeaders.add(lowerHeader);\n  }\n\n  return normalizedTrustedProxyHeaders;\n}\n\n/**\n * Parses the standard `Forwarded` header (RFC 7239).\n * It extracts the parameters from the first (leftmost) element in the header.\n *\n * @param headerValue - The value of the `Forwarded` header.\n * @returns A record of lowercase parameter names to their values.\n */\nexport function parseForwardedHeader(\n  headerValue: string | null | undefined,","sourceCodeStart":257,"sourceCodeEnd":293,"githubUrl":"https://github.com/angular/angular-cli/blob/bb72145f9ab45aee29f523236b3a25cd0813a841/packages/angular/ssr/src/utils/validation.ts#L257-L293","documentation":"`normalizeTrustProxyHeaders` enforces that every entry of `trustProxyHeaders` is either the literal `forwarded` header or starts with `x-forwarded-` (case-insensitive). Any other header name — e.g. `x-real-ip`, `host`, or a typo — is rejected with this error, restricting the trust scope to standard proxy forwarding headers.","triggerScenarios":"Passing `trustProxyHeaders: ['x-real-ip']`, `['X-Forwarded Host']` (space typo), `['x-forwarded']` is valid but `['forwarded-for']` or any non-proxy header throws during server construction or normalization.","commonSituations":"Trusting legacy proxy headers like x-real-ip or client-ip; typos such as `x-forwardedhost` or `x_forwarded_proto`; upgrading Angular SSR and migrating an allowlist that previously accepted arbitrary names.","solutions":["Rename entries to valid proxy headers: `forwarded` or names starting with `x-forwarded-` (e.g. `x-forwarded-for`).","Fix typos/spaces/case (case is normalized, but spelling must be exact).","If you rely on `x-real-ip` etc., configure your proxy to also emit the equivalent `x-forwarded-*` header and trust that instead.","Use `'*'` only as the standalone trust-all sentinel, never per-header."],"exampleFix":"// before\nnew AngularServerApp({ trustProxyHeaders: ['x-real-ip', 'X-Forwarded Proto'] });\n// after\nnew AngularServerApp({ trustProxyHeaders: ['x-forwarded-for', 'x-forwarded-proto'] });","handlingStrategy":"validation","validationCode":"const isValidProxyHeader = (h: string) =>\n  h === 'forwarded' || h.startsWith('x-forwarded-');\nfor (const h of ['x-real-ip']) {\n  if (!isValidProxyHeader(h.toLowerCase())) throw new Error(`\"${h}\" is not a valid proxy header`);\n}","typeGuard":"const isProxyHeaderName = (h: string): h is 'forwarded' | `x-forwarded-${string}` =>\n  h === 'forwarded' || h.startsWith('x-forwarded-');","tryCatchPattern":"try {\n  const app = new AngularServerApp({ trustProxyHeaders: cfg.trustProxyHeaders });\n} catch (e) {\n  if ((e as Error).message.includes('not a valid proxy header')) {\n    console.error('Remove non-proxy headers from trustProxyHeaders:', (e as Error).message);\n  }\n  throw e;\n}","preventionTips":["Whitelist only `forwarded` and `x-forwarded-*` names in your config schema.","Check spelling/hyphens carefully; casing does not matter but text does.","Map legacy headers (x-real-ip, client-ip) to x-forwarded-* equivalents at the proxy."],"tags":["angular","ssr","configuration","security","validation"],"backgroundTag":"invalid-configuration-value","analyzedSha":"bb72145f9ab45aee29f523236b3a25cd0813a841","analyzedAt":"2026-08-30T02:47:34.745Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}