{"record":{"id":"c92c866db9e63a6b","repo":"musistudio/claude-code-router","slug":"failed-to-start-mitm-server-for-hostname","errorCode":null,"errorMessage":"Failed to start MITM server for ${hostname}","messagePattern":"Failed to start MITM server for (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/proxy/service.ts","lineNumber":690,"sourceCode":"    const authority = this.authority ?? readProxyCertificateAuthority();\n    const certificate = createCertificateForHost(hostname, authority);\n    const server = https.createServer(\n      {\n        ALPNProtocols: [\"http/1.1\"],\n        cert: certificate.cert,\n        key: certificate.key\n      },\n      (request, response) => {\n        void this.handleProxyRequest(request, response, \"https:\").catch((error) => {\n          sendProxyError(response, 502, formatError(error));\n        });\n      }\n    );\n    await listen(server, 0, \"127.0.0.1\");\n    const address = server.address();\n    if (!address || typeof address === \"string\") {\n      await closeServer(server);\n      throw new Error(`Failed to start MITM server for ${hostname}`);\n    }\n    return {\n      host: hostname,\n      port: address.port,\n      server\n    };\n  }\n\n  private async handleProxyRequest(request: IncomingMessage, response: ServerResponse, defaultProtocol: \"http:\" | \"https:\"): Promise<void> {\n    if (!this.config) {\n      sendProxyError(response, 503, \"Proxy service is not configured.\");\n      return;\n    }\n\n    const requestId = randomUUID();\n    const targetUrl = resolveRequestUrl(request, defaultProtocol);\n    const pluginRoute = pluginService.resolveProxyRoute(targetUrl);\n    if (!pluginRoute && isCursorAgentProxyRequest(targetUrl)) {","sourceCodeStart":672,"sourceCodeEnd":708,"githubUrl":"https://github.com/musistudio/claude-code-router/blob/99f24806c6a2c660b16e53e95211c517448a6c90/packages/core/src/proxy/service.ts#L672-L708","documentation":"The proxy service failed to bind a local MITM listener for a CONNECTed hostname. After calling listen(server, 0, \"127.0.0.1\"), server.address() returned null or a string (pipe name), which should not happen for a TCP listener, so the half-started server is closed and this error thrown.","triggerScenarios":"CONNECT tunneling to a hostname when the ephemeral 127.0.0.1 listener fails to yield an inet address: address exhaustion (no free ports), file descriptor limits, or an unexpected server state where address() is null right after listen.","commonSituations":"Heavy parallel CONNECT tunnels exhausting ephemeral ports or fd ulimit; embedded environment with restricted networking; races where the server closes immediately after listen.","solutions":["Retry the CONNECT request (transient bind failure) after a short delay","Raise fd/ephemeral port limits (ulimit -n, net.ipv4.ip_local_port_range) if many tunnels are open","Reduce concurrent MITM connections or reuse the existing MITM server for that hostname","Inspect system-level socket exhaustion (ss -s, lsof) if it persists"],"exampleFix":"// before\nconst mitm = await proxy.getMitmServer(hostname); // throws\n\n// after\nimport { retry } from \"./retry\";\nconst mitm = await retry(() => proxy.getMitmServer(hostname), { attempts: 3, backoffMs: 200 });","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { return await withMitm(hostname); } catch (e) { if (e.message.includes(\"Failed to start MITM server\")) return await delayThenRetry(200, () => withMitm(hostname)); throw e; }","preventionTips":["Bound concurrent CONNECT tunnels per process","Monitor ephemeral port and fd usage","Retry transient bind failures with backoff"],"tags":["proxy","mitm","listen","port-bind","connect-tunnel"],"backgroundTag":"address-in-use","analyzedSha":"99f24806c6a2c660b16e53e95211c517448a6c90","analyzedAt":"2026-08-27T04:11:01.184Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}