musistudio/claude-code-router · error · Error

CONNECT target is missing.

Error message

CONNECT target is missing.

What it means

An HTTPS CONNECT request had no target in its request line. The CONNECT method requires 'host:port' as the request target; the proxy throws when request.url is undefined/empty.

Source

Thrown at packages/core/src/proxy/service.ts:1353

  return new URL(`${targetUrl.pathname}${targetUrl.search}`, `http://${gatewayHost}:${config.gateway.port}`);
}

function resolveRequestUrl(request: IncomingMessage, defaultProtocol: "http:" | "https:"): URL {
  const rawUrl = request.url || "/";
  if (/^https?:\/\//i.test(rawUrl)) {
    return new URL(rawUrl);
  }

  const host = readHeader(request.headers.host);
  if (!host) {
    throw new Error("Proxy request is missing Host header.");
  }
  return new URL(`${defaultProtocol}//${host}${rawUrl.startsWith("/") ? rawUrl : `/${rawUrl}`}`);
}

function parseConnectTarget(value: string | undefined): { hostname: string; port: number } {
  if (!value) {
    throw new Error("CONNECT target is missing.");
  }
  const parsed = new URL(`http://${value}`);
  return {
    hostname: parsed.hostname,
    port: parsed.port ? Number(parsed.port) : 443
  };
}

function proxyEndpoint(config: AppConfig): string {
  const host = config.proxy.host === "0.0.0.0" ? "127.0.0.1" : config.proxy.host;
  return `http://${host}:${config.proxy.port}`;
}

function sharedProxyEndpoint(config: AppConfig): string {
  const host = config.gateway.host === "0.0.0.0" ? "127.0.0.1" : config.gateway.host;
  return `http://${host}:${config.gateway.port}`;
}

View on GitHub (pinned to 99f24806c6)

Solutions

  1. Ensure HTTPS clients use the proxy as an HTTP CONNECT proxy (https-proxy-agent / standard proxy settings), not a raw TLS endpoint
  2. If writing a custom client, always send 'CONNECT host:port HTTP/1.1' with a non-empty authority
  3. Verify the client's proxy configuration URL/port

Example fix

// before
socket.write("CONNECT  HTTP/1.1\r\n\r\n"); // throws

// after
socket.write("CONNECT example.com:443 HTTP/1.1\r\nHost: example.com:443\r\n\r\n");
Defensive patterns

Strategy: validation

Validate before calling

if (!req.url || !/^[^\s:]+:\d+$/.test(req.url)) {
  socket.end("HTTP/1.1 400 Bad Request\r\n\r\n");
  return;
}

Type guard

function isValidConnectTarget(url: string | undefined): url is string {
  return typeof url === "string" && /^[^\s:]+:\d+$/.test(url);
}

Try / catch

try { await handleConnect(req, socket, head); } catch (e) { if (e.message.includes("CONNECT target")) { socket.end("HTTP/1.1 400 Bad Request\r\n\r\n"); return; } throw e; }

Prevention

When it happens

Trigger: A client opens a CONNECT tunnel with an empty request target — raw socket clients that send 'CONNECT HTTP/1.1', or a TLS connection mistakenly handled as CONNECT due to routing/proxy configuration.

Common situations: Pointing an HTTPS client directly (not via proxy) at the proxy port so bytes are misinterpreted; hand-written tunnel clients; proxies chained incorrectly sending CONNECT with no authority component.

Related errors


AI-assisted analysis of musistudio/claude-code-router@99f24806c6 (2026-08-27). Data as JSON: /api/errors/c1a51848db737bc5. Report an issue: GitHub.