ArmorDB Logo
ArmorDB
Fix Postgresql No Pg Hba Conf Entry
How to Fix PostgreSQL `no pg_hba.conf entry for host` Errors
Back to Blog
Quick Fixes
June 5, 2026
5 min read

How to Fix PostgreSQL `no pg_hba.conf entry for host` Errors

A practical guide to diagnosing PostgreSQL pg_hba.conf host, user, database, address, and SSL mismatches without weakening database access rules.

AE
ArmorDB EngineeringArmorDB engineering
PostgreSQLpg_hba.confAuthentication

The PostgreSQL error no pg_hba.conf entry for host means the server reached authentication, looked through its host-based access rules, and found no rule that matched this connection. It is not usually a password problem. It is an allowlist problem: the combination of client address, database, user, connection type, and sometimes SSL state does not match any row PostgreSQL is willing to use.

The fastest fix is not to add a broad host all all 0.0.0.0/0 rule and move on. That can make the error disappear while exposing the database more than intended. A good fix identifies the connection PostgreSQL is seeing, adds the narrowest correct rule, reloads configuration, and verifies that the application is still using TLS when production requires it.

Why this error happens

PostgreSQL checks client authentication with pg_hba.conf, the host-based authentication file documented in the official PostgreSQL manual. Each row describes a connection type, databases, users, client address range, and authentication method. Rows are checked in order, and the first matching row controls what happens next.

That order matters. A narrow rule below a broader reject rule may never be reached. A rule for localhost does not match a container, CI runner, or application server connecting over a private network address. A rule written as hostssl only matches SSL connections, while hostnossl only matches non-SSL connections. If the address and user look right but the SSL state differs, PostgreSQL can still report that no usable entry exists.

Managed PostgreSQL users usually do not edit pg_hba.conf directly. The same concepts still apply through the provider dashboard: IP allowlists, private networking, required SSL modes, database roles, and connection strings are the managed version of the same access decision. If you use ArmorDB, start with the connection details in the dashboard and the connection docs before changing application secrets.

Read the error as a five-part mismatch

The useful way to debug the message is to treat it as a tuple. PostgreSQL is trying to match connection type, host address, database name, user name, and SSL state. Find the mismatch instead of changing all five at once.

Error detail to checkWhat it usually meansSafer fix
Host addressThe server sees a different IP than you expected, often NAT, Docker, Kubernetes, or a cloud egress IP.Add the real egress CIDR or use private networking; avoid 0.0.0.0/0 for production.
Database nameThe rule allows a different database or the app defaults to the user name as database.Set the database explicitly in the connection string and match that name in the rule.
User nameThe app is connecting as a role not covered by the rule.Fix the secret or add a role-specific rule with the intended auth method.
SSL stateThe rule requires SSL but the client did not negotiate it, or the reverse.Use the correct sslmode and prefer SSL for internet-facing production connections.
Rule orderA preceding rule matches or rejects before the intended rule is considered.Put narrow, intentional rules before broad fallbacks and reload PostgreSQL.

Step-by-step fix

Start by capturing the exact error from the application log or psql. PostgreSQL often includes details such as host "203.0.113.10", user "app", database "appdb", SSL off. Those details are more reliable than what you think the app is configured to use, because they describe the connection as the server received it.

Next, confirm the connection string. For psql, make the parameters explicit so defaults do not hide the problem:

psql "host=db.example.com port=5432 dbname=appdb user=app sslmode=require"

If that succeeds while the application fails, compare the application's resolved environment variables. Frameworks and ORMs often split connection settings across DATABASE_URL, SSL options, and pooler-specific variables. A missing database name or a different username is enough to trigger this error.

For self-hosted PostgreSQL, add the narrow rule that matches the real tuple. A typical SSL-only application rule looks like this:

# TYPE    DATABASE  USER  ADDRESS          METHOD
hostssl   appdb     app   203.0.113.0/24   scram-sha-256

The authentication method should match your security posture and server configuration. Current PostgreSQL documentation describes scram-sha-256 as a password authentication method and pg_hba.conf as the place where that method is selected for matching clients. If your cluster still uses older password settings, do not mix authentication changes into the emergency access fix unless you have tested them first.

Reload PostgreSQL after editing the file. A reload is enough for pg_hba.conf changes; a full restart is usually unnecessary and adds avoidable risk.

SELECT pg_reload_conf();

Then retry with the same client command. If it still fails, check rule order and SSL state before widening the address range. In containerized systems, also check whether the server sees the pod IP, node IP, load balancer address, or NAT gateway. The right rule is for the source address PostgreSQL actually receives.

Common variants

When the error includes SSL off, the client did not connect with SSL even if the server supports it. Set sslmode=require or the stricter mode your environment uses. PostgreSQL's libpq documentation explains the SSL modes; the important practical point is that prefer can behave differently from require when you expected a hard TLS requirement.

When the error only happens from production but not your laptop, the production egress address is probably different from the address in the allowlist. Cloud deployments frequently egress through NAT gateways, build runners, serverless infrastructure, or a private network path. Update the allowlist to the stable production egress range rather than each ephemeral instance.

When it appears after moving to PgBouncer, verify which host the application reaches and which credentials are presented to PostgreSQL behind the pooler. Pooling changes connection topology. It should not require broad database access, but it may mean the database sees the pooler's address rather than the original application host. For related pooling behavior, see the ArmorDB guide to PgBouncer pooling modes.

What not to do

Do not solve the incident by adding a global trust rule. trust authentication tells PostgreSQL to accept the connection without a password for matching clients. That may be tolerable in a tightly controlled local development socket, but it is a dangerous production shortcut.

Do not leave temporary CIDR ranges behind after debugging. If you widen a rule for an incident, put the cleanup in the same change ticket or deployment notes. Access rules tend to become invisible once the application is working again, and stale allowlists are exactly the kind of quiet configuration drift that creates security exposure later.

Takeaway

no pg_hba.conf entry for host is PostgreSQL saying that the connection never matched an allowed access rule. Fix the specific mismatch: source address, database, role, SSL state, or rule order. Keep the rule narrow, reload configuration, and validate with an explicit connection string before changing application code.

For managed PostgreSQL, translate the same workflow into provider settings: confirm the dashboard connection string, allowed network path, required SSL mode, and role. That gives you the speed of a quick fix without turning an authentication error into a broader security problem.

Sources / further reading

Topic

Quick Fixes

Updated

Jun 5, 2026

Read time

5 min read

About the author

ArmorDB Engineering writes about PostgreSQL operations, security, and infrastructure decisions for teams building production apps on ArmorDB.