{"record":{"id":"1aedf2065d877898","repo":"headroomlabs-ai/headroom","slug":"headroom-proxy-not-reachable-at-expliciturl-en","errorCode":null,"errorMessage":"Headroom proxy not reachable at ${explicitUrl}. Ensure the proxy is running first.","messagePattern":"Headroom proxy not reachable at (.+?)\\. Ensure the proxy is running first\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"plugins/openclaw/src/proxy-manager.ts","lineNumber":143,"sourceCode":"      );\n      await this.startHeadroomProxy(startupUrl, port);\n\n      const startedProbe = await waitForHeadroomProxy(\n        startupUrl,\n        this.config.startupTimeoutMs ?? 20_000,\n      );\n      if (startedProbe.reachable && startedProbe.isHeadroom) {\n        this.proxyUrl = startupUrl;\n        this.logger.info(`Headroom proxy started and reachable at ${startupUrl}`);\n        return startupUrl;\n      }\n      throw new Error(\n        `Attempted to start Headroom proxy, but it was not reachable at ${startupUrl} (${startedProbe.reason ?? \"unknown\"}).`,\n      );\n    }\n\n    if (explicitUrl) {\n      throw new Error(\n        `Headroom proxy not reachable at ${explicitUrl}. Ensure the proxy is running first.`,\n      );\n    }\n\n    throw new Error(\n      `Headroom proxy not detected on default endpoints (${defaultCandidates.join(\", \")}). ` +\n        \"Set proxyUrl explicitly or enable autoStart.\",\n    );\n  }\n\n  private getProxyPort(): number {\n    const rawPort = this.config.proxyPort;\n    if (!Number.isInteger(rawPort) || rawPort === undefined) return 8787;\n    if (rawPort < 1 || rawPort > 65535) {\n      throw new Error(\"proxyPort must be an integer between 1 and 65535\");\n    }\n    return rawPort;\n  }","sourceCodeStart":125,"sourceCodeEnd":161,"githubUrl":"https://github.com/headroomlabs-ai/headroom/blob/322425c43bffde1ed0b64fecf3cf5951565dd82b/plugins/openclaw/src/proxy-manager.ts#L125-L161","documentation":"An explicit local proxyUrl was configured, the probe found nothing (or nothing Headroom-like) there, auto-start is not enabled, so the manager has no way to bring the proxy up and refuses to proceed. This is the connect-only failure for local explicit URLs; it never spawns a process unless autoStart is true.","triggerScenarios":"proxyUrl set to a local address (e.g. http://127.0.0.1:8787), autoStart unset/false, and no Headroom proxy currently listening at that address — not started, crashed, or listening on a different port.","commonSituations":"Forgetting to launch 'headroom proxy' before starting the client; proxy crashed in the background; port mismatch between the headroom CLI invocation and the client config; assuming the client auto-starts the proxy when autoStart was explicitly disabled.","solutions":["Start the proxy at the configured address: headroom proxy --host 127.0.0.1 --port <same-port-as-proxyUrl>","If you want the client to handle startup, enable autoStart in the manager config","Correct a port/host typo in proxyUrl so it matches where Headroom actually listens"],"exampleFix":"# before: client configured but proxy never started\nmanager.configure({ proxyUrl: \"http://127.0.0.1:8787\" });\n\n# after: start the proxy first, or let the manager do it\nheadroom proxy --port 8787 &\n# or: manager.configure({ proxyUrl: \"http://127.0.0.1:8787\", autoStart: true });","handlingStrategy":"validation","validationCode":"import { probeHeadroomProxy } from \"./proxy-probe.js\";\n\nconst proxyUrl = \"http://127.0.0.1:8787\";\nconst probe = await probeHeadroomProxy(proxyUrl);\nif (!(probe.reachable && probe.isHeadroom)) {\n  throw new Error(`No Headroom proxy at ${proxyUrl} (${probe.reason}); start it or enable autoStart`);","typeGuard":"interface Probe { reachable: boolean; isHeadroom: boolean }\n\nfunction isUsableProxy(probe: Probe | null | undefined): probe is Probe & { reachable: true; isHeadroom: true } {\n  return Boolean(probe?.reachable && probe?.isHeadroom);\n}","tryCatchPattern":"try {\n  await manager.resolveProxyUrl();\n} catch (e) {\n  if (e instanceof Error && e.message.includes(\"Ensure the proxy is running first\")) {\n    throw new Error(\"Startup order bug: launch the Headroom proxy before the client (or set autoStart)\");\n  }\n  throw e;\n}","preventionTips":["Make 'start proxy, then start client' an explicit step in runbooks and docker-compose depends_on ordering","Enable autoStart for local dev so a forgotten manual launch cannot break startup","Health-check the proxy URL during boot and fail fast with a clear message"],"tags":["proxy","configuration","openclaw"],"backgroundTag":null,"analyzedSha":"322425c43bffde1ed0b64fecf3cf5951565dd82b","analyzedAt":"2026-08-15T01:03:05.481Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}