Skip to content
Latchkey

PostgreSQL "FATAL: role ... does not exist" in CI

Postgres started fine and accepted the connection, but the role (user) your connection string asks for does not exist. The official image only creates the role named in POSTGRES_USER (default postgres).

What this error means

The connection is refused at authentication with "FATAL: role \"app\" does not exist" or "FATAL: role \"root\" does not exist", even though the container is healthy.

Terminal
psql: error: connection to server at "localhost" (127.0.0.1), port 5432 failed:
FATAL:  role "app" does not exist

Common causes

POSTGRES_USER was not set on the service

The image creates a superuser from POSTGRES_USER, defaulting to postgres. If your app connects as app or root and you never set that env, the role is absent.

The connection string user does not match the container env

A DATABASE_URL that names a different user than the one the container created will fail at login with this exact FATAL.

How to fix it

Create the role via the image env vars

Set POSTGRES_USER (and password) so the entrypoint creates exactly the role your app connects as.

.github/workflows/ci.yml
services:
  postgres:
    image: postgres:16
    env:
      POSTGRES_USER: app
      POSTGRES_PASSWORD: app_pw
      POSTGRES_DB: app_test
    ports: ['5432:5432']

Align the connection string with the created role

Make the user in DATABASE_URL match POSTGRES_USER.

Terminal
DATABASE_URL=postgresql://app:app_pw@localhost:5432/app_test

How to prevent it

  • Set POSTGRES_USER/POSTGRES_PASSWORD/POSTGRES_DB to match your app config.
  • Derive the CI DATABASE_URL from the same values you pass to the container.
  • Remember the default superuser is postgres, not root.

Frequently asked questions

What causes "Postgres "FATAL: role does not exist""?
The image creates a superuser from POSTGRES_USER, defaulting to postgres. If your app connects as app or root and you never set that env, the role is absent.
How do I fix Postgres "FATAL: role does not exist"?
Set POSTGRES_USER (and password) so the entrypoint creates exactly the role your app connects as.

Related guides

References

Latchkey auto-heals failures like this one - detected, fixed, and retried without you. Start free → 30-day trial · No credit card