angular/angular · error · RuntimeError

INVALID_URL

INVALID_URL

Error message

Invalid URL: ${urlStr}

What it means

resolveUrl() in platform-server first tries `new URL(urlStr)`; if that fails it checks `URL.canParse(urlStr, 'http://fake')` to detect inputs that carry a scheme (e.g. `http:`) but are malformed absolute URLs, such as a double port `http://host:8080:9090/`. Per the WHATWG spec such input parses strictly against the base and still fails, so the flow throws INVALID_URL rather than silently resolving a broken absolute URL against the app origin.

Source

Thrown at packages/platform-server/src/url.ts:83

    resolved = new URL(urlStr);
  } catch {}
  const {allowProtocolRelative = false, allowOriginChange = true} = options;

  if (resolved) {
    if (originUrl && !isSafeOriginChange(resolved, originUrl, urlStr, allowOriginChange)) {
      throwSuspiciousUrlError(urlStr);
    }

    return resolved;
  }

  // We identify and throw on malformed absolute URLs (like double port).
  // Per the WHATWG URL standard, parsing an input starting with a scheme (like 'http:') against
  // a standard base (like 'http://fake') ignores the base argument and parses strictly as an
  // absolute URL. Since it is malformed, the native URL constructor will throw a validation
  // error. Standard relative/protocol-relative paths parse successfully, allowing the flow to continue.
  if (!URL.canParse(urlStr, 'http://fake')) {
    throw new RuntimeError(
      RuntimeErrorCode.INVALID_URL,
      typeof ngDevMode === 'undefined' || ngDevMode ? `Invalid URL: ${urlStr}` : urlStr,
    );
  }

  if (!originUrl) {
    return null;
  }

  // Check if we have a legitimate protocol-relative URL (starts with '//' and not a duplicate/backslash bypass)
  // and we are configured to allow and preserve standard cross-origin protocol-relative requests.
  if (urlStr.startsWith('//')) {
    if (!allowProtocolRelative) {
      throw new RuntimeError(
        RuntimeErrorCode.PROTOCOL_RELATIVE_URL_NOT_ALLOWED,
        typeof ngDevMode === 'undefined' || ngDevMode
          ? `Protocol relative URLs are not allowed in this context. URL: ${urlStr}`
          : urlStr,

View on GitHub (pinned to 51cb07e980)

Solutions

  1. Fix the URL string itself — remove the duplicate port/whitespace/invalid characters (the message prints the exact offending URL)
  2. Validate with `URL.canParse(url)` (or try `new URL(url)`) before passing the URL into renderApplication/INITIAL_CONFIG
  3. Check proxy header handling (Host, X-Forwarded-Host, X-Forwarded-Port) that builds the URL server-side

Example fix

// before
const url = `${protocol}//${host}:${port}:${altPort}/app`; // double port
await renderApplication(bootstrap, {url}); // Invalid URL

// after
const url = `${protocol}//${host}:${port}/app`;
if (!URL.canParse(url)) throw new Error(`Bad request URL: ${url}`);
await renderApplication(bootstrap, {url});
Defensive patterns

Strategy: validation

Validate before calling

// Validate before passing to renderApplication / INITIAL_CONFIG
function isParseableAbsoluteUrl(url: string): boolean {
  return URL.canParse(url);
}

if (!isParseableAbsoluteUrl(requestUrl)) {
  throw new Error(`Refusing to render: malformed request URL ${JSON.stringify(requestUrl)}`);
}

Try / catch

try {
  await renderApplication(bootstrap, {url});
} catch (e) {
  if (e instanceof Error && e.message.startsWith('Invalid URL:')) {
    // log the offending URL and reject the request with 400
    respond400(`Malformed request URL: ${url}`);
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: Passing a scheme-bearing malformed URL to any resolveUrl consumer: the `url` option of renderApplication/renderModule, INITIAL_CONFIG `{url: ...}` for ServerPlatformLocation, or the platform-server relative-URL interceptor receiving e.g. `http://host:8080:8080/path`, `https://exa mple.com`, or `https://[bad`.

Common situations: Reverse proxies forwarding malformed Host or X-Forwarded-Host headers that produce double-port URLs; environment variables or config files supplying a malformed absolute URL; string concatenation bugs when assembling request URLs on the server.

Related errors


AI-assisted analysis of angular/angular@51cb07e980 (2026-08-22). Data as JSON: /api/errors/903c0dafa2278553. Report an issue: GitHub.