Skip to content
Latchkey

FastAPI "httpx.ConnectError: Connection refused" in CI

An httpx client tried to reach your app but nothing was listening on that host and port yet. In CI the server either had not finished its startup, crashed on boot, or is bound to a different address than the test uses.

What this error means

A test using httpx against a live server fails with "httpx.ConnectError: [Errno 111] Connection refused" while unit tests pass.

python
httpx.ConnectError: [Errno 111] Connection refused

The above exception was the direct cause of the following exception:
httpx.ConnectError

Common causes

The request raced ahead of server startup

The test fired before uvicorn finished binding, so the connection was refused. CI runners are often slower to boot than a laptop.

The server crashed during startup or bound another address

A lifespan or import error killed the server, or it listens on 127.0.0.1 while the test targets a different host.

How to fix it

Wait for readiness before requesting

  1. Poll a health endpoint until it responds instead of sleeping a fixed time.
  2. Confirm the client base URL matches the host and port uvicorn bound.
  3. Check the server log for a startup exception if it never becomes ready.
tests/conftest.py
import httpx, time

def wait_ready(url, timeout=30):
    deadline = time.time() + timeout
    while time.time() < deadline:
        try:
            if httpx.get(url).status_code == 200:
                return
        except httpx.ConnectError:
            time.sleep(0.5)
    raise RuntimeError("server never became ready")

Drive the app in-process instead

Use httpx.ASGITransport (or TestClient) to call the app object directly, removing the socket and the startup race entirely.

tests/test_api.py
import httpx
from app.main import app

transport = httpx.ASGITransport(app=app)
async with httpx.AsyncClient(transport=transport, base_url="http://test") as ac:
    r = await ac.get("/health")

How to prevent it

  • Poll a readiness endpoint rather than sleeping a fixed interval.
  • Prefer in-process ASGI transport for endpoint tests.
  • Log and surface startup exceptions so a crashed boot is not mistaken for a race.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →