PostgreSQL Container “FATAL: password authentication failed for user “postgres”” — Docker Network Socket Resolution

Environment Context: PostgreSQL 18.1 on Docker Compose

  • Component/Version: PostgreSQL 18.1 (Debian 18.1-1.pgdg13+2)
  • Deployment Method: Docker Compose with declared service, volume, and custom network
  • Host OS: Linux (unspecified distribution; container base is Debian trixie)
  • Port Mapping5432:5432
  • Environment VariablePOSTGRES_PASSWORD=postgres
  • Volumepostgres_data:/var/lib/postgresql
  • Network: Custom bridge network react-2.0_net_dev
  • Relevant Config Paths:
    • Data directory: /var/lib/postgresql
    • pg_hba.conf location: /var/lib/postgresql/18/docker/pg_hba.conf

Raw Error Log: Authentication Failure and Role Absence

The following errors appeared in container logs and during interactive shell attempts:

2026-04-22 05:29:23.308 UTC [77] FATAL:  password authentication failed for user "postgres"
2026-04-22 05:29:23.308 UTC [77] DETAIL: Connection matched file "/var/lib/postgresql/18/docker/pg_hba.conf" line 128: "host all all all scram-sha-256"
PostgreSQL server log showing FATAL password authentication failed for user postgres

When attempting to connect via psql inside the container without specifying a user:

root@bc2c1ce69477:/# psql
psql: error: connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed: FATAL: role "root" does not
exist
Terminal output showing PostgreSQL psql FATAL role root does not exist error inside container

Failed Attempts: Why psql Without Flags and Prisma Studio Defaults Failed

  • Connecting via psql with no arguments: The PostgreSQL client defaults to the current operating system user (root) as the database role. Since no root role exists in the PostgreSQL instance, the connection was rejected.
  • Connecting via psql -U postgres (without -h): This command succeeded in establishing a local socket connection, but Prisma Studio continued to fail. The socket-based connection (/var/run/postgresql/.s.PGSQL.5432) worked for psql because the container’s local Unix-domain socket is accessible by default, but Prisma Studio’s connection logic (and many application-level clients) defaults to TCP/IP over localhost or the container’s hostname. The socket path does not resolve to a TCP endpoint that Prisma Studio can use without explicit host configuration.
  • Relying solely on the POSTGRES_PASSWORD environment variable: The password was correctly set (postgres), but password authentication failure persisted because the client was not connecting to the expected TCP/IP endpoint. The pg_hba.conf line host all all all scram-sha-256 permits password-based authentication over TCP/IP, but the client must actually use TCP/IP for that rule to apply. Socket connections follow a different local authentication line (typically peer or md5), which was not the root cause here.

The Solution: Explicitly Specify -h localhost for TCP/IP Connections

The issue was resolved by forcing the PostgreSQL client to connect via TCP/IP to localhost rather than relying on the default Unix-domain socket.

Permanent fix (inside the container or from the host):

psql -U postgres -h localhost

This command explicitly instructs psql to use TCP/IP over the loopback interface, which matches the host all all all scram-sha-256 rule in pg_hba.conf and prompts for the password correctly.

For Prisma Studio (or any application‑level client), ensure the database connection string includes the host parameter:

DATABASE_URL="postgresql://postgres:postgres@localhost:5432/postgres?schema=public"

or, if connecting from outside the container:

DATABASE_URL="postgresql://postgres:[email protected]:5432/postgres?schema=public"

Why this works:
PostgreSQL’s libpq client library prioritizes Unix-domain sockets when no host is specified. On Docker, the socket path (/var/run/postgresql/.s.PGSQL.5432) is valid, but many tools (Prisma Studio, ORMs, and connection poolers) expect a TCP hostname. Explicitly setting -h localhost (or host=localhost in a connection string) forces TCP/IP and triggers the correct pg_hba.conf authentication rule.

Temporary workaround (if you cannot modify the connection string):
Exec into the container and use psql -U postgres -h localhost to perform manual operations. Note that this does not fix external clients — they require the host parameter in their connection URIs.


References


(Last verified: 22 April 2026 — PostgreSQL 18.1, Debian trixie)