headroomlabs-ai/headroom · error · RuntimeError
Proxy failed to start on port {port} within {timeout_seconds
Error message
Proxy failed to start on port {port} within {timeout_seconds} seconds. Set {_WRAP_PROXY_TIMEOUT_ENV} to a larger number of seconds for slow startup. What it means
Headroom spawns the proxy and polls its health endpoint once per second for timeout_seconds (from HEADROOM_WRAP_PROXY_TIMEOUT or the default). If the timeout elapses while the process is still alive but not yet healthy, Headroom kills the child (proc.kill()) and raises this RuntimeError, suggesting the timeout env var for slow machines. Unlike the 'exited with code' error, the process here was alive but unresponsive/slow.
Source
Thrown at headroom/cli/wrap.py:808
# Wait for proxy to be ready.
# ML components (Kompress, Magika, Tree-sitter) load synchronously before
# uvicorn binds the port. On slower machines this can take 20-30 seconds.
for _i in range(timeout_seconds):
time.sleep(1)
if _check_proxy(port):
click.echo(f" Logs: {log_path}")
return proc
# Check if process died
if proc.poll() is not None:
# Read last few lines of log for error context
try:
tail = _read_text(stdio_log_path)[-500:]
except Exception:
tail = "(no log output)"
raise RuntimeError(f"Proxy exited with code {proc.returncode}: {tail}")
proc.kill()
raise RuntimeError(
f"Proxy failed to start on port {port} within {timeout_seconds} seconds. "
f"Set {_WRAP_PROXY_TIMEOUT_ENV} to a larger number of seconds for slow startup."
)
finally:
stdio_log_file.close()
# CLI context tools (rtk, lean-ctx) were removed from Headroom. The selector is
# kept only long enough to fail loudly: it lives in shell profiles, scripts and
# CI jobs, and silently ignoring it would look like Headroom had stopped working.
# See :mod:`headroom.context_tool_cleanup`, which uninstalls what they left behind.
_RETIRED_CONTEXT_TOOL_ENV = "HEADROOM_CONTEXT_TOOL"
_RETIRED_CONTEXT_TOOL_MESSAGE = (
"CLI context tools (rtk, lean-ctx) have been removed from Headroom: they "
"rewrote shell commands through a third-party binary Headroom no longer "
"manages. Drop --context-tool / --no-context-tool and unset "
f"{_RETIRED_CONTEXT_TOOL_ENV}; `headroom wrap` uninstalls what they left "
"behind automatically."View on GitHub (pinned to 322425c43b)
Solutions
- Raise the timeout: export HEADROOM_WRAP_PROXY_TIMEOUT=120 (must be a plain positive integer)
- Check the proxy log (proxy.log and the stdio log) to see whether startup is progressing or hung on a network fetch
- Reduce startup cost: pre-warm caches, close heavy competing processes, or pin to a lighter backend
- If it hangs every time (not just slowly), inspect the log for a blocked health check or missing dependency and fix that root cause
Example fix
# before export HEADROOM_WRAP_PROXY_TIMEOUT=5 # too tight; proxy killed at 5s headroom wrap claude # after export HEADROOM_WRAP_PROXY_TIMEOUT=120 headroom wrap claude
Defensive patterns
Strategy: retry
Validate before calling
import os, time, urllib.request
def proxy_healthy(port: int) -> bool:
try:
urllib.request.urlopen(f"http://127.0.0.1:{port}/health", timeout=2)
return True
except OSError:
return False
# budget generously on slow machines before launching the wrap
os.environ.setdefault("HEADROOM_WRAP_PROXY_TIMEOUT", "120") Try / catch
for attempt in range(2):
try:
proc = start_proxy()
break
except RuntimeError as e:
if "failed to start on port" in str(e) and attempt == 0:
os.environ["HEADROOM_WRAP_PROXY_TIMEOUT"] = "180" # widen and retry once
continue
raise Prevention
- Set HEADROOM_WRAP_PROXY_TIMEOUT=120 on cold or constrained machines
- Pre-warm heavy dependencies once so later starts are fast
- Distinguish slow start (this error) from crash (exit-code error) before tuning the timeout
When it happens
Trigger: Slow proxy startup exceeding the configured timeout: cold Python import of heavy ML/tokenizer modules, slow first-run model downloads, a health endpoint blocked behind a dependency, heavy CPU load, or a timeout env var set too small (e.g. 1-2 seconds). The health check (_check_proxy) never succeeded within the window.
Common situations: First run on a new machine where dependencies warm caches; CI runners with constrained CPU; containerized environments with slow I/O; users who set HEADROOM_WRAP_PROXY_TIMEOUT to a very low value; network filesystems slowing module import.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Proxy exited with code {proc.returncode}: {tail}
- headroom proxy was not ready at {url}: {last_error}
- recommendations IO error at {path}: {source}
- bedrock_eventstream_crc_mismatch
- Proxy process exited unexpectedly.
AI-assisted analysis of headroomlabs-ai/headroom@322425c43b (2026-08-15).
Data as JSON: /api/errors/c0483a35f2656eb3.
Report an issue: GitHub.