angular/angular-cli · error · Error

"${header}" is not a valid proxy header. Trusted proxy heade

Error message

"${header}" is not a valid proxy header. Trusted proxy headers must be "forwarded" or start with "x-forwarded-".

What it means

`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.

Source

Thrown at packages/angular/ssr/src/utils/validation.ts:275

  if (!trustProxyHeaders) {
    return new Set();
  }

  if (trustProxyHeaders === true) {
    return new Set([TRUST_ALL_PROXY_HEADERS]);
  }

  const normalizedTrustedProxyHeaders = new Set<string>();
  for (const header of trustProxyHeaders) {
    const lowerHeader = header.toLowerCase();
    if (lowerHeader === TRUST_ALL_PROXY_HEADERS) {
      throw new Error(
        `"${TRUST_ALL_PROXY_HEADERS}" is not allowed as a value for the "trustProxyHeaders" option.`,
      );
    }
    const isValid = lowerHeader === 'forwarded' || lowerHeader.startsWith('x-forwarded-');
    if (!isValid) {
      throw new Error(
        `"${header}" is not a valid proxy header. Trusted proxy headers must be "forwarded" or start with "x-forwarded-".`,
      );
    }
    normalizedTrustedProxyHeaders.add(lowerHeader);
  }

  return normalizedTrustedProxyHeaders;
}

/**
 * Parses the standard `Forwarded` header (RFC 7239).
 * It extracts the parameters from the first (leftmost) element in the header.
 *
 * @param headerValue - The value of the `Forwarded` header.
 * @returns A record of lowercase parameter names to their values.
 */
export function parseForwardedHeader(
  headerValue: string | null | undefined,

View on GitHub (pinned to bb72145f9a)

Solutions

  1. Rename entries to valid proxy headers: `forwarded` or names starting with `x-forwarded-` (e.g. `x-forwarded-for`).
  2. Fix typos/spaces/case (case is normalized, but spelling must be exact).
  3. If you rely on `x-real-ip` etc., configure your proxy to also emit the equivalent `x-forwarded-*` header and trust that instead.
  4. Use `'*'` only as the standalone trust-all sentinel, never per-header.

Example fix

// before
new AngularServerApp({ trustProxyHeaders: ['x-real-ip', 'X-Forwarded Proto'] });
// after
new AngularServerApp({ trustProxyHeaders: ['x-forwarded-for', 'x-forwarded-proto'] });
Defensive patterns

Strategy: validation

Validate before calling

const isValidProxyHeader = (h: string) =>
  h === 'forwarded' || h.startsWith('x-forwarded-');
for (const h of ['x-real-ip']) {
  if (!isValidProxyHeader(h.toLowerCase())) throw new Error(`"${h}" is not a valid proxy header`);
}

Type guard

const isProxyHeaderName = (h: string): h is 'forwarded' | `x-forwarded-${string}` =>
  h === 'forwarded' || h.startsWith('x-forwarded-');

Try / catch

try {
  const app = new AngularServerApp({ trustProxyHeaders: cfg.trustProxyHeaders });
} catch (e) {
  if ((e as Error).message.includes('not a valid proxy header')) {
    console.error('Remove non-proxy headers from trustProxyHeaders:', (e as Error).message);
  }
  throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "Invalid configuration value" and "Unsupported/Unknown setting value" errors: why libraries reject your config strings, numbers, and types — this error's family across 30 libraries.

Related errors


AI-assisted analysis of angular/angular-cli@bb72145f9a (2026-08-30). Data as JSON: /api/errors/1402ba1f1aa42b88. Report an issue: GitHub.