This error occurs when PostgreSQL receives a connection attempt but cannot find a matching rule in the pg_hba.conf configuration file. It typically happens when connecting from an IP address, hostname, or with a user/database combination that isn't explicitly allowed. Add the missing entry to pg_hba.conf and reload the database to fix it.
PostgreSQL uses a Host-Based Authentication (HBA) configuration file called pg_hba.conf to control client access. When a client attempts to connect, PostgreSQL checks pg_hba.conf sequentially for a matching rule based on connection type (local socket, TCP/IP, SSL), client IP address, database name, username, and authentication method. If no matching rule is found, the connection is rejected with this error. This is a security feature that prevents unauthorized access, but it requires explicit configuration to allow legitimate connections.
Determine which IP address the client is connecting from. The error message usually includes this information. For example:
FATAL: no pg_hba.conf entry for host "192.168.1.100", user "myuser", database "mydb", SSL offThis tells you:
- Client IP: 192.168.1.100
- User: myuser
- Database: mydb
- Connection type: TCP/IP without SSL (host)
If connecting from localhost/127.0.0.1, the error typically indicates a 'local' socket or 'host' with loopback IP.
Find where pg_hba.conf is stored on your PostgreSQL server:
Linux/Unix:
# Typical locations
/etc/postgresql/VERSION/main/pg_hba.conf
/var/lib/postgresql/VERSION/main/pg_hba.conf
/usr/local/var/postgres/pg_hba.conf (macOS)Windows:
C:\Program Files\PostgreSQL\VERSION\data\pg_hba.confFind via psql (if you have local access):
sudo -u postgres psql -c "SHOW hba_file;"This command shows the exact path PostgreSQL is using.
Open pg_hba.conf in a text editor and examine existing rules. The format is:
TYPE DATABASE USER CIDR-ADDRESS METHODExample entries:
# Local connections (Unix socket)
local all all peer
# IPv4 localhost
host all all 127.0.0.1/32 scram-sha-256
# IPv6 localhost
host all all ::1/128 scram-sha-256
# Remote IPv4 connections
host all all 192.168.1.0/24 scram-sha-256
# Reject all other connections
host all all 0.0.0.0/0 rejectNote that rules are evaluated in order—the first matching rule wins. Rules that appear early must be more specific than later rules.
Based on the error message, add a new rule for the client IP. Place it BEFORE any 'reject' rules, otherwise the reject will match first and your new rule will never be reached:
For the example error (192.168.1.100, user myuser, database mydb):
# Allow myuser from 192.168.1.100
host mydb myuser 192.168.1.100/32 scram-sha-256
# Or allow all users from that network
host all all 192.168.1.0/24 scram-sha-256Choose the authentication method:
- scram-sha-256 - Strongest password method and the recommended default (PostgreSQL 10+, default since 14). Prefer this for all network connections.
- md5 - Legacy password method. It is cryptographically weaker than SCRAM and vulnerable to known attacks, so prefer scram-sha-256 wherever your clients support it. Note that md5 is kept mainly for old client compatibility; if you switch a user to scram-sha-256, the stored password must be SCRAM-hashed (set password_encryption = 'scram-sha-256' in postgresql.conf and reset the user's password with ALTER ROLE myuser PASSWORD '...';) or authentication will fail.
- trust - DANGEROUS: allows connection with NO password whatsoever for ANYONE whose connection matches the rule (IP/user/database). It performs zero authentication. Never use trust for host/hostssl (networked) rules, and never combine it with a broad CIDR such as 192.168.1.0/24 or 0.0.0.0/0 — doing so hands your database to anyone who can reach the port. It is only ever acceptable for tightly-scoped local development (e.g. a local Unix-socket rule on a single-user machine). For remote access always use scram-sha-256.
- reject - Deny the connection.
CIDR notation:
- 192.168.1.100/32 - Single IP address (most secure; grant the narrowest range that works)
- 192.168.1.0/24 - Network (192.168.1.0 to 192.168.1.255)
- 0.0.0.0/0 - All IPv4 addresses (not recommended in production)
Fixing pg_hba.conf only controls *which* clients are authorized. PostgreSQL must also be *listening* on the network interface the client connects to, which is governed by listen_addresses in postgresql.conf. If pg_hba.conf is correct but listen_addresses = 'localhost' (the common default), remote clients will no longer hit the pg_hba error — instead they'll get connection refused/could not connect, and it's easy to wrongly conclude the pg_hba fix failed.
Check the current value:
sudo -u postgres psql -c "SHOW listen_addresses;"
sudo -u postgres psql -c "SHOW config_file;" # path to postgresql.confEdit postgresql.conf to listen on the relevant interface:
# Bind to a SPECIFIC address the clients reach (preferred)
listen_addresses = 'localhost,10.0.0.5'
# '*' listens on ALL interfaces — only do this when the host is
# firewalled/in a private network, since it exposes the port broadly.
# listen_addresses = '*'For security, bind to the specific private/internal address(es) you actually need rather than blindly using '*', and keep the port behind a firewall or security group. Note that listen_addresses is not reloadable — changing it requires a full restart (not just pg_reload_conf()):
sudo systemctl restart postgresqlVerify the server is listening where you expect:
ss -ltnp | grep 5432Apply the pg_hba.conf changes by reloading the configuration. (pg_hba.conf changes only need a reload; a listen_addresses change from the previous step requires a full restart.)
Reload (no downtime, sufficient for pg_hba.conf):
# Linux with systemd
sudo systemctl reload postgresql
# Or with pg_ctl
pg_ctl reload -D /path/to/data/directory
# Or from psql (as superuser)
SELECT pg_reload_conf();If reload fails or doesn't work, restart PostgreSQL:
# Linux with systemd
sudo systemctl restart postgresql
# Or with pg_ctl
pg_ctl restart -D /path/to/data/directory
# macOS with Homebrew
brew services restart postgresql
# Docker
docker restart postgres_container_nameReload is preferred for pg_hba.conf because it doesn't drop existing connections.
Confirm PostgreSQL parsed your rules as expected using the pg_hba_file_rules view (PostgreSQL 10+), which surfaces parse errors per line:
SELECT line_number, type, database, user_name, address, auth_method, error
FROM pg_hba_file_rules;Any non-null error column points to a malformed line that was ignored.
Test from the client machine:
psql -h postgres-server-ip -U myuser -d mydbFrom the PostgreSQL server (if connecting locally):
psql -h 127.0.0.1 -U myuser -d mydbIn application connection strings:
postgresql://myuser:password@postgres-host:5432/mydbIf the error persists, check PostgreSQL logs for more details:
# Linux
sudo tail -50 /var/log/postgresql/postgresql.log
# Or from psql
SELECT pg_current_logfile();CIDR Matching: PostgreSQL matches IP addresses against pg_hba.conf rules using CIDR notation. A /32 suffix matches a single IPv4 address, while /24 matches a network of 256 addresses. IPv6 addresses use /128 for a single address and /64 for larger blocks. Rule Order Matters: pg_hba.conf is evaluated top-to-bottom and the first matching line wins. Place specific rules (single IPs, specific users) before general rules, and place any allow rule BEFORE a broad 'reject' rule. A 'reject' rule near the top will block all subsequent rules for matching connections. Auth method choice: Prefer scram-sha-256 over md5 for all networked rules; md5 is weaker and retained mainly for old client compatibility. Switching a role to SCRAM requires the stored password to be re-hashed under scram-sha-256 (set password_encryption and reset the password). Avoid trust entirely for host/hostssl rules — it disables authentication for every matching client. listen_addresses vs pg_hba.conf: These are independent layers. listen_addresses (postgresql.conf) decides which interfaces the server binds to and needs a restart to change; pg_hba.conf decides who is authorized and only needs a reload. A correct pg_hba.conf with listen_addresses = 'localhost' yields 'connection refused', not the pg_hba error. Bind to specific addresses rather than '*' when possible. SSL/TLS: Use 'hostssl' instead of 'host' to require encrypted connections, or 'hostnossl' for unencrypted only. Many production databases require SSL. Replication: If setting up replication, use the 'replication' database name: host replication all 192.168.1.100/32 scram-sha-256. Cloud Platforms: AWS RDS, Google Cloud SQL, and Azure Database for PostgreSQL usually manage pg_hba.conf automatically. If self-hosted in containers or VMs, ensure the CIDR block matches your network topology. Peer Authentication: The 'peer' method (common for local connections) requires the OS username to match the PostgreSQL username—it doesn't use passwords. Testing Configuration: PostgreSQL 10+ provides the pg_hba_file_rules view to see how rules are being interpreted, including parse errors: SELECT * FROM pg_hba_file_rules;
insufficient privilege to bypass row security
How to fix "insufficient privilege to bypass row security" in PostgreSQL
HV004: fdw_invalid_data_type
How to fix "HV004: fdw_invalid_data_type" in PostgreSQL
insufficient columns in unique constraint for partition key
How to fix "insufficient columns in unique constraint for partition key" in PostgreSQL
ERROR 42501: must be owner of table
How to fix "must be owner of table" in PostgreSQL
trigger cannot change partition destination
How to fix "Trigger cannot change partition destination" in PostgreSQL