BerriAI/litellm · error · ProcessLaunchError

Ephemeral proxy never became healthy within {timeout}s. Last

Error message

Ephemeral proxy never became healthy within {timeout}s. Last log lines:
{_tail(log_path)}

What it means

Raised by poll_liveliness when the ephemeral proxy subprocess started for autoroute never answered /health/liveliness within the timeout window (the process dying earlier has its own error). The message embeds the timeout and the tail of the captured proxy log so the operator can see why the proxy failed to become healthy — usually a bad config or port conflict.

Source

Thrown at litellm/proxy/client/cli/commands/autoroute/process.py:108

    if not log_path.exists():
        return "(no log output captured)"
    return "\n".join(log_path.read_text(errors="replace").splitlines()[-lines:])


def poll_liveliness(base_url: str, log_path: Path, process: "subprocess.Popen[bytes]", timeout: float = 30.0) -> None:
    """Poll /health/liveliness until it responds, the process dies, or timeout elapses."""
    deadline: Final = time.monotonic() + timeout
    url: Final = base_url.rstrip("/") + "/health/liveliness"
    while time.monotonic() < deadline:
        if process.poll() is not None:
            raise ProcessLaunchError(
                f"Ephemeral proxy exited early (code {process.returncode}). Last log lines:\n{_tail(log_path)}"
            )
        with contextlib.suppress(requests.RequestException):
            if requests.get(url, timeout=2).status_code == 200:
                return
        time.sleep(0.5)
    raise ProcessLaunchError(
        f"Ephemeral proxy never became healthy within {timeout}s. Last log lines:\n{_tail(log_path)}"
    )


def write_pid_record(record: PidRecord, path: Path | None = None) -> None:
    resolved_path: Final = path if path is not None else PID_RECORD_PATH
    resolved_path.parent.mkdir(parents=True, exist_ok=True)
    with open(resolved_path, "w") as f:
        json.dump(
            {"pid": record.pid, "port": record.port, "config_path": record.config_path, "log_path": record.log_path},
            f,
            indent=2,
        )


def read_pid_record(path: Path | None = None) -> PidRecord | None:
    resolved_path: Final = path if path is not None else PID_RECORD_PATH
    if not resolved_path.exists():

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. Inspect the last log lines for startup errors.
  2. Increase the timeout or fix the blocking startup issue (port in use, bad config).

Example fix

Check the log file path in the error and resolve the reported startup failure.
Defensive patterns

Strategy: try-catch

When it happens

Trigger: Thrown at litellm/proxy/client/cli/commands/autoroute/process.py:108 when the library encounters an invalid state.

Common situations: The ephemeral proxy did not pass its health check within the timeout.

Understand the failure class


AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18). Data as JSON: /api/errors/ccf6fa8d39a7fedb. Report an issue: GitHub.