2026.10 / database authentication 068
Coolify PostgreSQL “no pg_hba.conf entry”: fix the actual mismatch
A Coolify application reaches PostgreSQL, but the database rejects it with an error shaped like this:
FATAL: no pg_hba.conf entry for host "CLIENT_ADDRESS",
user "APP_ROLE", database "APP_DATABASE", SSL off
This is not a generic “database is down” message. PostgreSQL’s own documentation says it means the client reached the server, but no host-based authentication rule matched that connection. The error already gives four useful facts: client address, requested role, requested database and, when shown, whether the attempt used TLS.
The dangerous response is to append host all all 0.0.0.0/0 trust or publish port 5432. That removes authentication instead of repairing it. The safe response is to identify why the expected rule did not match, make the smallest persistent change, reload PostgreSQL, and prove both the intended connection and a negative case.
pg_hba.conf is an ordered access policy, not a firewall substitute and not a password file. First matching rule wins; if no rule matches, PostgreSQL denies the connection.
What the error proves—and what it does not
| Observation | Meaning |
|---|---|
no pg_hba.conf entry | DNS, routing and TCP reached a PostgreSQL server; its host-authentication policy found no matching rule. |
SSL off | This attempt was unencrypted. A policy containing only hostssl rules cannot match it. |
SSL encryption in the message | The attempt used TLS, but its address, database, user or rule type still did not match. |
password authentication failed | A rule did match and selected password authentication; use the separate credential-drift workflow. |
connection refused or timeout | The request has not reached this authentication layer yet. |
Do not change Cloudflare DNS, application passwords or PostgreSQL storage permissions for a true HBA mismatch. If the error is actually loopback, name resolution, refusal or timeout, start with the Coolify PostgreSQL connection guide.
1. Capture the exact tuple without leaking credentials
Read the application error and PostgreSQL log from the same attempt. Record privately:
- the client address PostgreSQL reports;
- the exact database and role names;
- whether the message says
SSL offor an encrypted connection; - the database resource and deployment which produced the log;
- whether the application used Coolify’s Internal URL or a public endpoint.
Do not paste the connection URL: it normally contains a password. Do not assume the address in the error is a stable container identity either. Containers can be recreated with a new address, so authorization should normally describe the intended private network range or deployment boundary rather than one ephemeral address.
2. Confirm the app is using the intended Coolify path
Coolify recommends its Internal URL for applications on the same destination network and warns against exposing 5432 unless an external client genuinely requires it. Confirm the current application container received the intended runtime variable, without printing its value. Then resolve and test the database hostname from that container or an equivalent disposable container on the same network.
# Use the hostname and network discovered from Coolify;
# never paste a credential-bearing URL into a public log.
getent hosts DATABASE_INTERNAL_HOST
nc -vz DATABASE_INTERNAL_HOST 5432
A successful port test followed by the HBA error confirms you are at the policy layer. If the application is accidentally using a public address from inside Coolify, fix the endpoint before broadening HBA. The public path may present a different client address, require TLS, and unnecessarily expose the service.
3. Find the active HBA file, not a guessed path
pg_hba.conf traditionally lives in the data directory, but PostgreSQL permits hba_file to point elsewhere. Query the running server as an existing administrative role over a trusted local path:
SHOW hba_file;
SHOW config_file;
SHOW ssl;
SHOW listen_addresses;
Keep the returned paths private. In a container, inspect the effective mount before editing anything. A change made only in a running container’s writable layer can disappear at recreation; a change made to the wrong data directory does nothing. For Coolify-managed resources, prefer supported database configuration and persistent mounts over an ad-hoc docker exec edit.
4. Inspect parsed rules and their order
When available, PostgreSQL’s pg_hba_file_rules view exposes parsed rules and syntax errors without printing passwords:
SELECT rule_number, type, database, user_name,
address, netmask, auth_method, error
FROM pg_hba_file_rules
ORDER BY rule_number;
Rules are considered in order. PostgreSQL uses the first record whose connection type, client address, database and role match. There is no fallback to a later rule when authentication under the chosen rule fails. Check all four matching dimensions:
- Type:
hostmatches TCP with or without TLS;hostsslmatches only TLS;hostnosslmatches only non-TLS. - Database: the requested database must match the rule’s database field.
- User: the requested PostgreSQL role must match the user field.
- Address: the reported client address must fall inside the rule’s IPv4 or IPv6 range. An IPv4 rule does not match IPv6, or vice versa.
If the view reports an error, repair the syntax before widening any scope. Also inspect include directives: the active policy may be assembled from multiple files, and included records are inserted at the directive’s position.
5. Resolve “SSL off” deliberately
SSL off often means the server has a hostssl rule while the application is making a non-TLS connection. Decide which side is wrong based on the actual trust boundary; do not merely suppress the suffix.
- If TLS is required, enable it on the Coolify PostgreSQL resource, copy the updated connection URL, configure the application’s documented SSL mode, and mount/trust the Coolify CA when using
verify-caorverify-full. - If a private-only Coolify network is intentionally allowed to connect without TLS, use a narrowly scoped
hostorhostnosslrule for that network, database and role—only after confirming that policy is acceptable. - If the client uses a public endpoint, do not downgrade it to non-TLS to make the error disappear. Repair certificate trust and hostname verification.
Coolify documents require, verify-ca and verify-full for encrypted PostgreSQL clients. require encrypts but does not validate the server identity; verify-full also checks the CA and hostname. Choose explicitly rather than inheriting a framework default you have not inspected.
6. Add the narrowest persistent rule
A least-privilege rule names the required database, role, private client range and password method. This is a shape, not a value to paste unchanged:
# TYPE DATABASE USER ADDRESS METHOD
hostssl APP_DATABASE APP_ROLE PRIVATE_CIDR scram-sha-256
Derive PRIVATE_CIDR from the effective Docker/Coolify network, not from an example on the internet and not from a single container address. If only one controlled external client is allowed, use its stable routed address with the smallest appropriate prefix and keep network-level filtering in place as well.
Avoid these shortcuts:
trust, which lets matching clients authenticate without a password;0.0.0.0/0or::/0when only a private range is required;allfor both database and user when one application role is known;- deprecated MD5 password storage as the default for a new rule;
- hard-coding one disposable container address;
- editing generated container files without making the source persistent.
Do not confuse listen_addresses with HBA. PostgreSQL must listen on an appropriate interface before HBA can evaluate remote TCP, but setting listen_addresses='*' does not authorize a client and can increase exposure. Keep the database private unless there is a documented external-access requirement.
7. Validate, reload, and confirm the active rule
After changing the persistent source, re-check pg_hba_file_rules for syntax errors. PostgreSQL normally rereads HBA after a reload, so a full database restart is not usually required for this file alone:
SELECT pg_reload_conf();
SELECT rule_number, type, database, user_name,
address, auth_method, error
FROM pg_hba_file_rules
ORDER BY rule_number;
If another configuration change such as enabling Coolify database SSL requires a stop and restart, follow Coolify’s documented sequence and take the normal backup precautions. Do not repeatedly recreate the resource just to test HBA; that adds unrelated network and container changes to a focused authentication incident.
8. Prove the fix from the application boundary
- Redeploy or restart only the consumers that need updated connection settings.
- Confirm the new application container uses the intended internal hostname and SSL mode without printing credentials.
- Run the application’s real connection or migration-status command.
- Load a route that requires an expected database row, not only a static health page.
- If safe, perform one disposable write, read it back, and remove it.
- Review PostgreSQL logs and confirm the HBA rejection has stopped.
- Test a deliberately unauthorized role, database or network boundary and confirm it is still denied.
- Verify scheduled backups still connect after the policy change.
A successful psql test from inside the database container is not enough: local socket rules differ from the application’s TCP rule. Likewise, a green Coolify health check does not prove the application role can reach its database over the intended route.
Compact troubleshooting order
- Capture the exact client address, database, role and TLS state from one attempt.
- Confirm the application uses the intended Coolify Internal URL or justified public path.
- Find the active
hba_fileand its persistent source. - Inspect parsed rules, include order and syntax errors.
- Match type, database, role, address family and CIDR in order.
- Resolve
SSL offaccording to the real trust boundary. - Add one narrow
scram-sha-256rule rather than a global bypass. - Reload and verify the parsed rule set.
- Prove a database-backed app path, backups and a negative authorization case.
The useful feature of this error is its precision. PostgreSQL has already told you that the connection reached the server and exactly which identity, database, address and encryption state failed to match. Preserve that evidence, repair the smallest policy boundary, and keep both the database port and the rule scope private.
Authoritative references: PostgreSQL explains the meaning of authentication errors and documents pg_hba.conf matching, ordering, record types and methods. Coolify’s official PostgreSQL guide recommends private Internal URLs and documents managed connection settings, while its database SSL guide covers certificate generation, client modes and CA trust.