headroomlabs-ai/headroom · error · Error
Headroom proxy not reachable at ${explicitUrl}. Ensure the p
Error message
Headroom proxy not reachable at ${explicitUrl}. Ensure the proxy is running first. What it means
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.
Source
Thrown at plugins/openclaw/src/proxy-manager.ts:143
);
await this.startHeadroomProxy(startupUrl, port);
const startedProbe = await waitForHeadroomProxy(
startupUrl,
this.config.startupTimeoutMs ?? 20_000,
);
if (startedProbe.reachable && startedProbe.isHeadroom) {
this.proxyUrl = startupUrl;
this.logger.info(`Headroom proxy started and reachable at ${startupUrl}`);
return startupUrl;
}
throw new Error(
`Attempted to start Headroom proxy, but it was not reachable at ${startupUrl} (${startedProbe.reason ?? "unknown"}).`,
);
}
if (explicitUrl) {
throw new Error(
`Headroom proxy not reachable at ${explicitUrl}. Ensure the proxy is running first.`,
);
}
throw new Error(
`Headroom proxy not detected on default endpoints (${defaultCandidates.join(", ")}). ` +
"Set proxyUrl explicitly or enable autoStart.",
);
}
private getProxyPort(): number {
const rawPort = this.config.proxyPort;
if (!Number.isInteger(rawPort) || rawPort === undefined) return 8787;
if (rawPort < 1 || rawPort > 65535) {
throw new Error("proxyPort must be an integer between 1 and 65535");
}
return rawPort;
}View on GitHub (pinned to 322425c43b)
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
Example fix
# before: client configured but proxy never started
manager.configure({ proxyUrl: "http://127.0.0.1:8787" });
# after: start the proxy first, or let the manager do it
headroom proxy --port 8787 &
# or: manager.configure({ proxyUrl: "http://127.0.0.1:8787", autoStart: true }); Defensive patterns
Strategy: validation
Validate before calling
import { probeHeadroomProxy } from "./proxy-probe.js";
const proxyUrl = "http://127.0.0.1:8787";
const probe = await probeHeadroomProxy(proxyUrl);
if (!(probe.reachable && probe.isHeadroom)) {
throw new Error(`No Headroom proxy at ${proxyUrl} (${probe.reason}); start it or enable autoStart`); Type guard
interface Probe { reachable: boolean; isHeadroom: boolean }
function isUsableProxy(probe: Probe | null | undefined): probe is Probe & { reachable: true; isHeadroom: true } {
return Boolean(probe?.reachable && probe?.isHeadroom);
} Try / catch
try {
await manager.resolveProxyUrl();
} catch (e) {
if (e instanceof Error && e.message.includes("Ensure the proxy is running first")) {
throw new Error("Startup order bug: launch the Headroom proxy before the client (or set autoStart)");
}
throw e;
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Headroom proxy startup is disabled
- Service reachable at ${explicitUrl}, but it does not appear
- Remote Headroom proxy not reachable at ${explicitUrl}. Ensur
- Headroom proxy not detected on default endpoints (${defaultC
- proxyPort must be an integer between 1 and 65535
AI-assisted analysis of headroomlabs-ai/headroom@322425c43b (2026-08-15).
Data as JSON: /api/errors/1aedf2065d877898.
Report an issue: GitHub.