Troubleshooting
PostgreSQL & databases

Fix PostgreSQL "No pg_hba.conf Entry for Host" in Django

Fix the PostgreSQL FATAL error no pg_hba.conf entry for host when Django connects: add the right host or hostssl rule, match the client address and auth method, reload PostgreSQL, and handle Docker networks and SSL-only managed databases.

Problem statement

Django can reach the database server, but the connection is refused immediately:

django.db.utils.OperationalError: connection to server at "10.0.1.20", port 5432
failed: FATAL:  no pg_hba.conf entry for host "10.0.2.15", user "app",
database "appdb", no encryption

PostgreSQL received the connection and checked its client authentication file, pg_hba.conf, from top to bottom. No line matched this combination of connection type, database, user, and client address, so it rejected the client before even asking for a password. The message tells you every value you need to write the missing rule.

How PostgreSQL decidesClient connectsfrom 10.0.2.15pg_hba.conf readfirst match winsNo line matchestype, db, user, IPFATAL rejectedbefore passwordRead the four values in the error and write exactly one rule that matches them.
  1. Read the error: client host, user, database, and whether it says no encryption or SSL encryption.
  2. Add a line to pg_hba.conf such as hostssl appdb app 10.0.2.0/24 scram-sha-256.
  3. Make sure listen_addresses in postgresql.conf includes the interface the app connects to.
  4. Reload: sudo systemctl reload postgresql or SELECT pg_reload_conf();.
  5. If the error says no encryption on a managed database, set sslmode=require in Django instead of editing rules.

Step-by-step solution

1. Locate the active file

sudo -u postgres psql -c "SHOW hba_file;"

On Debian and Ubuntu it is /etc/postgresql/<version>/main/pg_hba.conf; in the official Docker image it is /var/lib/postgresql/data/pg_hba.conf. Editing a different copy does nothing.

2. Write a rule that matches the error

Each line has the form TYPE DATABASE USER ADDRESS METHOD:

# TYPE    DATABASE  USER  ADDRESS        METHOD
hostssl   appdb     app   10.0.2.0/24    scram-sha-256
  • TYPE is host for TCP with or without TLS, hostssl for TLS only, hostnossl for plain TCP only, and local for Unix sockets.
  • ADDRESS is a CIDR range. Use the app server's subnet rather than 0.0.0.0/0.
  • METHOD should be scram-sha-256 for passwords on modern PostgreSQL.

Order matters: PostgreSQL uses the first matching line. A reject line or a stricter rule above yours wins.

one line that matches the error# TYPE    DATABASE  USER  ADDRESS       METHODhostsslappdb     app10.0.2.0/24scram-sha-2561231Requires TLS; use host if the error says no encryption on purpose.2The app subnet from the error, not 0.0.0.0/0.3Password hashing method; the user password must be stored as SCRAM.Every field maps to a value printed in the FATAL messagedjango-deployment.com
Narrow rules keep the database closed to every other host.

3. Check that PostgreSQL listens on that interface

A missing pg_hba.conf entry means the connection got through. But if you just moved the database to its own server, also confirm it listens on the private address:

# postgresql.conf
listen_addresses = 'localhost,10.0.1.20'

Changing listen_addresses needs a restart; pg_hba.conf changes only need a reload.

4. Reload and test

sudo systemctl reload postgresql
psql "host=10.0.1.20 dbname=appdb user=app sslmode=require" -c "select 1"

Run the test from the app server, not from the database host, so the client address matches what Django uses.

5. Docker and Kubernetes clients

Containers connect from their network's address, such as 172.18.0.5, not from the host's IP. The official Postgres image adds host all all all scram-sha-256 when POSTGRES_PASSWORD is set, so this error in Compose usually means a custom pg_hba.conf was mounted. Add the Docker network range (docker network inspect <name> shows it) or the pod CIDR in Kubernetes.

6. Managed databases that require SSL

RDS with rds.force_ssl=1, Azure Flexible Server, and many hosted providers allow only hostssl. The error then says no encryption, and the fix is on the Django side:

DATABASES["default"]["OPTIONS"] = {"sslmode": "require"}

You cannot edit pg_hba.conf on most managed services; use their firewall or network settings for address rules.

what the message tells youDetail in errorCause and fixno encryption, managed DBserver allows only TLS;set sslmode=requireunexpected 172.x addressDocker network sourceIP; allow that subnetcorrect host, other databaserule lists a differentDB; add or use allrule exists but still failsedited wrong file or notreloaded; check hba_fileThe message includes host, user, database, and encryptiondjango-deployment.com
Compare each field with your rule before widening anything.

Explanation

pg_hba.conf is PostgreSQL's gatekeeper for client authentication. It runs before password checking, so this error is different from "password authentication failed": the server did not even try a password. Because the first match wins and there is no default allow rule, any combination not described in the file is rejected. That makes the file safe but unforgiving when apps move to new subnets, containers, or TLS.

Edge cases / notes

  • IPv6. If Django connects to localhost and resolves ::1, you need a rule for ::1/128 as well as 127.0.0.1/32.
  • Replication rules. Replicas need replication in the database column; regular database rules do not cover them.
  • PgBouncer. With a pooler in front, the client address PostgreSQL sees is the pooler's, not the app's.

Next steps

FAQ

Is it safe to add host all all 0.0.0.0/0?

Only behind a firewall that already restricts access, and even then it is better to list the app subnets. A narrow rule documents who should connect.

Do I need to restart PostgreSQL after editing pg_hba.conf?

No, a reload is enough. Restart only when you change listen_addresses or other restart-only settings.

Why does psql on the database server work?

It connects over the local socket or from 127.0.0.1, which has its own rules. Test from the app server instead.

What does "no encryption" mean in the message?

The client connected without TLS. If the only matching rules are hostssl, enable SSL in Django's connection options.

Keep going