angular/angular-cli · error · Error

host value cannot be an array.

Error message

host value cannot be an array.

What it means

When building the request URL from a Node request, the code resolves the hostname from forwarded-host headers, the host header, or HTTP/2 :authority. If the resolved value is an array (duplicate/malformed headers), it throws because a single host string is required.

Source

Thrown at packages/angular/ssr/node/src/request.ts:142

    originalUrl,
  } = nodeRequest as IncomingMessage & { originalUrl?: string };

  const forwardedHeaderValue = getAllowedProxyHeaderValue(headers, 'forwarded', trustProxyHeaders);
  const forwardedParams = parseForwardedHeader(forwardedHeaderValue);

  const protocol =
    forwardedParams.proto ??
    getAllowedProxyHeaderValue(headers, 'x-forwarded-proto', trustProxyHeaders) ??
    ('encrypted' in socket && socket.encrypted ? 'https' : 'http');

  const hostname =
    forwardedParams.host ??
    getAllowedProxyHeaderValue(headers, 'x-forwarded-host', trustProxyHeaders) ??
    headers.host ??
    headers[':authority'];

  if (Array.isArray(hostname)) {
    throw new Error('host value cannot be an array.');
  }

  let hostnameWithPort = hostname;
  if (!hostname?.includes(':')) {
    const port = getAllowedProxyHeaderValue(headers, 'x-forwarded-port', trustProxyHeaders);
    if (port) {
      hostnameWithPort += `:${port}`;
    }
  }

  return new URL(`${protocol}://${hostnameWithPort}${originalUrl ?? url}`);
}

/**
 * Gets the first value of an allowed proxy header.
 *
 * @param headers - The Node.js incoming HTTP headers.
 * @param headerName - The name of the proxy header to retrieve.

View on GitHub (pinned to bb72145f9a)

Solutions

  1. Fix the proxy to overwrite (not append) x-forwarded-host: e.g. nginx `proxy_set_header X-Forwarded-Host $host;`
  2. Deduplicate headers in middleware before handing the request to Angular SSR
  3. Set trustProxyHeaders appropriately so only the intended header is honored
  4. Normalize headers.host to a string in a custom server wrapper before render

Example fix

// before (nginx appends)
proxy_set_header X-Forwarded-Host $proxy_add_x_forwarded_host;
// after (overwrites)
proxy_set_header X-Forwarded-Host $host;
Defensive patterns

Strategy: validation

Validate before calling

const host = req.headers['x-forwarded-host'] ?? req.headers.host;
if (Array.isArray(host)) {
  console.error('Duplicate host header from proxy; fix upstream before SSR');
  return new Response('Bad Request', { status: 400 });
}

Type guard

function isSingleHeader(v: string | string[] | undefined): v is string {
  return typeof v === 'string';
}

Try / catch

try {
  const url = createRequestUrl(req);
} catch (e) {
  if (e instanceof Error && e.message.includes('host value cannot be an array')) {
    return new Response('Bad Request: duplicate host header', { status: 400 });
  }
  throw e;
}

Prevention

When it happens

Trigger: Node requests where headers.host, x-forwarded-host, or :authority parsed as an array (repeated headers), typically behind misconfigured proxies/load balancers sending the header twice.

Common situations: Reverse proxies (nginx/HAProxy) appending rather than setting x-forwarded-host, HTTP/2 with duplicate pseudo-headers, hand-crafted requests with duplicated Host headers.

Related errors


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