Postgres Error: 'no pg_hba.conf entry for host' — Cause, Fix, and Troubleshooting Guide
Fix Postgres 'no pg_hba.conf entry for host': add a host/hostssl CIDR rule with scram-sha-256, open listen_addresses, then reload.
- #postgres
- #postgresql
- #database
- #troubleshooting
Stuck on this Postgres error? Get the free incident triage checklist
A one-page PDF — the exact steps to isolate, fix, and verify a production error like this one. No spam, unsubscribe anytime.
Overview
PostgreSQL rejects a connection with this error when the client reached the server, but no line in pg_hba.conf matched the combination of client IP, user, database, and connection type (plain vs SSL). Host-based authentication (hba) is a first-match ordered allowlist; if nothing matches, the connection is refused before any password is even checked.
FATAL: no pg_hba.conf entry for host "10.0.3.44", user "app_user", database "appdb", no encryption
Every field in that message is a clue. The host 10.0.3.44 must fall inside a rule’s CIDR, app_user and appdb must be permitted by that rule, and the trailing no encryption means the client connected without SSL — so any hostssl-only rule was skipped. Fixing this is about adding or correcting one line, then reloading (not restarting).
Symptoms
- The client connects far enough to get a
FATAL, unlikeConnection refusedwhere nothing is listening. - The error names the exact host, user, database, and whether encryption was used.
- Connections work from one subnet or host but fail from a new one (new pod CIDR, new NAT IP, new office range).
- Switching a client between SSL and non-SSL flips it between working and failing.
psql: error: connection to server at "db.internal" (10.0.1.10), port 5432 failed:
FATAL: no pg_hba.conf entry for host "10.0.3.44", user "app_user", database "appdb", no encryption
Common Root Causes
1. Client IP not covered by any rule’s CIDR
The most common cause: the client’s address falls outside every address/mask in the file. A new subnet, a rotated NAT gateway, or an IPv6 address where only IPv4 is allowed all produce this.
SELECT type, database, user_name, address, netmask, auth_method
FROM pg_hba_file_rules
ORDER BY line_number;
If 10.0.3.44 is not inside any listed address, no rule can match.
2. SSL required but the client connected in plaintext (or vice versa)
hostssl rules match only encrypted connections; hostnossl only unencrypted; host matches either. The no encryption tail means the client used plaintext, so any hostssl-only entry for its range was passed over and nothing else matched.
3. Rule order — first match wins
pg_hba.conf is evaluated top to bottom and stops at the first line whose type/database/user/address all match. A broad reject or a narrower earlier rule can shadow the line you intended to use.
4. Wrong database or user in an otherwise-matching rule
A rule that allows app_user to appdb will not cover app_user connecting to orders, nor a different role connecting to appdb. The database and user columns must include the requested values (or be all).
5. listen_addresses not opened
If the server never listened on the interface the client reached, you would usually see Connection refused — but a misconfigured listen_addresses combined with partial binding is worth confirming while you are in the file.
How to diagnose
Step 1: Locate the active hba file and read the rules
SHOW hba_file;
SELECT line_number, type, database, user_name, address, auth_method, error
FROM pg_hba_file_rules
ORDER BY line_number;
line_number | type | database | user_name | address | auth_method | error
-------------+-------+----------+-------------+--------------+--------------+-------
80 | local | {all} | {all} | | peer |
82 | host | {all} | {all} | 127.0.0.1 | scram-sha-256|
84 | host | {appdb} | {app_user} | 10.0.1.0 | scram-sha-256|
(3 rows)
Here app_user/appdb is only allowed from 10.0.1.0/24, so 10.0.3.44 has no matching rule. A non-null error column flags a malformed line.
Step 2: Confirm what the server is listening on
SHOW listen_addresses;
listen_addresses
------------------
*
(1 row)
* (or a list including the reachable interface) confirms the client can actually connect; localhost alone would block all remote clients.
Step 3: Read the exact rejection in the server log
The FATAL line in the server log restates the host, user, database, and encryption state exactly as the server evaluated them — trust those values over what you think the client sent (proxies and NAT can rewrite the source IP).
Fixes
Add a matching host rule with the right CIDR and method
Add a line to pg_hba.conf that covers the client’s real subnet, the target user and database, and use scram-sha-256 for password auth. Place it before any broad reject.
# TYPE DATABASE USER ADDRESS METHOD
host appdb app_user 10.0.3.0/24 scram-sha-256
Use hostssl (or host) to match the client’s encryption
If you require TLS, use hostssl and make sure the client connects with sslmode=require or stronger. If the client legitimately connects in plaintext on a trusted network, use host (matches both) so the no encryption connection is accepted.
hostssl appdb app_user 10.0.3.0/24 scram-sha-256
Reload — do not restart
pg_hba.conf changes take effect on a reload; a full restart is unnecessary and disruptive.
SELECT pg_reload_conf();
pg_reload_conf
----------------
t
(1 row)
Then re-check pg_hba_file_rules to confirm the new line loaded without an error.
Open listen_addresses if the server is not reachable remotely
ALTER SYSTEM SET listen_addresses = '*';
-- listen_addresses requires a restart to take effect
Unlike pg_hba.conf, listen_addresses needs a server restart, not just a reload.
What to watch out for
pg_hba.confis first-match-wins and top-to-bottom — put specific rules above broadreject/alllines or they will never be reached.- The
no encryptiontail is a real filter: ahostssl-only rule will silently skip a plaintext client, andhostmatches both. - Trust the IP in the server log, not the client — NAT, load balancers, and PgBouncer can change the source address the server actually sees.
- Prefer
scram-sha-256over the deprecatedmd5; the client library and stored password must both support it. SELECT * FROM pg_hba_file_rulesshows what is loaded; after editing, reload and re-query to confirm there is no parseerrorbefore you rely on it.
Related
- Postgres Error: ‘could not connect to server: Connection refused’
- Postgres Error: ‘password authentication failed for user’
- Postgres Error: ‘role ”…” does not exist’
Fixed it? Get 500 Postgres & DevOps AI prompts — free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.
Did this fix your issue?
Get 500 Battle-Tested DevOps AI Prompts — Free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.