Skip to content
Latchkey

FastAPI lifespan startup error crashes the app in CI

An exception raised inside your lifespan context manager (or a legacy @app.on_event("startup") handler) stops the app from starting. uvicorn logs "Application startup failed" and exits, and TestClient re-raises the error when it enters the app.

What this error means

uvicorn prints "ERROR: Application startup failed. Exiting." or TestClient raises during context entry, usually pointing at a database connection, a missing setting, or a migration call.

python
ERROR:    Traceback (most recent call last):
  File ".../starlette/routing.py", line ..., in lifespan
    async with self.lifespan_context(app):
  File "app/main.py", line 18, in lifespan
    await database.connect()
ConnectionRefusedError: [Errno 111] Connection refused
ERROR:    Application startup failed. Exiting.

Common causes

A dependency the startup needs is absent in CI

The lifespan connects to a database, cache, or external service that runs locally but is not provisioned as a CI service.

A required setting is missing in the CI environment

A startup handler reads a config value that is unset in CI, so it raises before the app is ready.

How to fix it

Provision the startup dependencies as CI services

Add the database or cache the lifespan needs as a service container so the connection in startup succeeds.

.github/workflows/ci.yml
services:
  postgres:
    image: postgres:16
    env:
      POSTGRES_PASSWORD: postgres
    ports: ['5432:5432']
    options: >-
      --health-cmd "pg_isready" --health-interval 10s
      --health-timeout 5s --health-retries 5

Make startup side effects optional in tests

Guard external connections so unit tests can enter the app without a live service, or override the lifespan in the test app.

app/main.py
from contextlib import asynccontextmanager

@asynccontextmanager
async def lifespan(app):
    if not app.state.testing:
        await database.connect()
    yield

How to prevent it

  • Provision every startup dependency as a CI service with a healthcheck.
  • Set all required settings in the CI job environment.
  • Keep startup side effects skippable or overridable under test.

Related guides

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