Skip to content
PostgreSQL

PostgreSQL Error 28000

no pg_hba.conf entry for host

Applies to: PostgreSQL 13 to 18
Last technically reviewed 24 October 2026 on PostgreSQL 18.6 documentation; SQL-level parts in PGlite 0.5.11
The full message
FATAL:  no pg_hba.conf entry for host "123.123.123.123", user "andym", database "testdb"
Other forms of this message
Current servers end the line with the encryption state (wording from the PostgreSQL 18.6 source)
FATAL:  no pg_hba.conf entry for host "123.123.123.123", user "andym", database "testdb", no encryption
The role does not exist (as documented in the tutorial)
FATAL:  role "joe" does not exist
Older wording of the same case, as printed on the Authentication Problems page
FATAL:  user "andym" does not exist
Peer authentication on a local socket (wording from the PostgreSQL 18.6 source)
FATAL:  Peer authentication failed for user "postgres"
A role without the LOGIN attribute (wording from the PostgreSQL 18.6 source)
FATAL:  role "report_reader" is not permitted to log in
A pg_hba.conf line with the reject method (wording from the PostgreSQL 18.6 source)
FATAL:  pg_hba.conf rejects connection for host "123.123.123.123", user "andym", database "testdb", no encryption
SQLSTATE
28000
Condition name
invalid_authorization_specification
Product
PostgreSQL
Versions
PostgreSQL 13 to 18
Last reviewed
24 October 2026

What it means

SQLSTATE 28000 means the server refused the login before or instead of a password check: no pg_hba.conf line allows this connection, the role does not exist or cannot log in, or peer or ident authentication did not match.

Every connection is checked against pg_hba.conf from the top, using the connection type (local socket, host, hostssl, hostnossl), the database, the role and the client address. With no pg_hba.conf entry for host ..., no line matched at all, so the server refused the connection without asking for a password. The documentation describes this as having contacted the server but the server not wanting to talk to you. The address in the message is the client address as the server sees it, which behind NAT, a proxy or a container network may not be the one you expect. Current servers add the encryption state at the end (no encryption, SSL encryption or GSS encryption), which matters when the only matching lines are hostssl or hostnossl.

The same SQLSTATE, 28000 (invalid_authorization_specification), covers the other refusals that are not a wrong password: the role named in the connection does not exist, the role exists but lacks the LOGIN attribute, or a peer or ident rule found that the operating system user does not match the database role. A wrong password is 28P01 instead. psql and other libpq programs print the server message after their own connection to server ... failed: prefix, and the server log often has more detail than the client.

Common causes

  • pg_hba.conf has no line for the client's address range, for example after moving the application to a new subnet, container network or cloud region.
  • The only matching line is hostssl but the client connects without SSL (the message ends with "no encryption"), or the line names a different database or role.
  • pg_hba.conf was edited but the server configuration was not reloaded, or a syntax error in the new line means it is not loaded.
  • The role in the connection does not exist: by default libpq uses the operating system user name, so running psql as another OS user tries a role of that name. (Where the matching line uses a password method, a missing role is reported as 28P01 instead.)
  • A local peer rule is used and the operating system user does not match the database role (for example running psql -U postgres as your own OS account).
  • The role was created with NOLOGIN (CREATE ROLE without LOGIN), which is normal for group roles.

Diagnose it

Read-only These queries only read the system catalogs (pg_catalog, information_schema) and statistics views such as pg_stat_activity and pg_locks. They do not change data, roles or settings, so they are safe to run first.

List the pg_hba.conf rules as the server reads them

pg_hba_file_rules shows the file currently on disk, in order, parsed by the server (superusers only). Compare each line's type, database, user_name and address with the connection that failed: the first match wins, and if none matches you get this error.

SELECT rule_number, line_number, type, database, user_name,
       address, netmask, auth_method, error
FROM pg_hba_file_rules
ORDER BY rule_number;
What to look for

A non-null error means a line has a syntax problem and is not loaded. Remember that the file on disk may differ from what the server is using until the configuration is reloaded.

Where is pg_hba.conf?

SELECT current_setting('hba_file') AS hba_file,
       current_setting('ssl') AS ssl;
What to look for

The full path of the file to edit, and whether the server accepts SSL connections (needed for hostssl lines).

Does the role exist and can it log in?

SELECT rolname, rolcanlogin
FROM pg_roles
WHERE rolname IN ('andym', 'joe');
What to look for

No row: the role does not exist. rolcanlogin = false: the role exists but needs the LOGIN attribute before anyone can connect as it.

Which address does the server see for a client?

From a connection that works, made from the same client machine (for example with a temporary narrow rule or from a jump host), check the address the server records. That is the address your pg_hba.conf line must cover.

SELECT inet_client_addr() AS client_address,
       current_user,
       current_database();
What to look for

The client address as the server sees it; NULL for a Unix-domain socket connection, which matches local lines rather than host lines.

How to fix it

Each fix is labelled with what it changes. Try read-only checks and the least invasive fix first, and test changes outside production.

Add a narrow pg_hba.conf line and reload

Changes configuration

Add a line for exactly the database, role and address range that should connect, with a password method, above any broader line that would match first. Then reload the configuration (pg_ctl reload, or the SQL function below). Do not use the trust method or open the server to all addresses to make the error go away.

Caution: A reload applies every pending change in the configuration files, not only this line. Check pg_hba_file_rules for errors first, and keep the address range as narrow as possible.

# pg_hba.conf
# TYPE   DATABASE  USER   ADDRESS             METHOD
hostssl  testdb    andym  123.123.123.123/32  scram-sha-256

-- then, as a superuser:
SELECT pg_reload_conf();

Connect with SSL when the rule is hostssl

Client or network side

If the message ends with no encryption and the matching rules are hostssl, the client must use SSL: add sslmode=require (or verify-full with the server certificate) to the connection string.

Create the role, or allow it to log in

Changes permissions

For "role ... does not exist", create the role (or connect with the right role name using -U or user=). For "is not permitted to log in", give the role the LOGIN attribute, unless it is a group role that should stay NOLOGIN; then log in as a member role instead.

CREATE ROLE joe LOGIN PASSWORD 'a-long-random-password';

ALTER ROLE report_reader LOGIN;

Match peer authentication, or use a password rule

Client or network side

A local peer rule only lets operating system user X log in as role X. Run the client as the matching OS user (for example sudo -u postgres psql), set up a user name map in pg_ident.conf, or connect over TCP (psql -h localhost) so that a host line with scram-sha-256 applies.

Examples

A client address with no matching pg_hba.conf line

Shown as documented in the PostgreSQL documentation (Client Authentication, Authentication Problems). A PostgreSQL 18 server also appends the encryption state, for example ", no encryption" (see the variants above). This example needs a running PostgreSQL server (a login over TCP checked against pg_hba.conf rules), which PGlite does not provide, so it was not reproduced here.

-- From the client machine 123.123.123.123:
-- psql "host=db.example.com dbname=testdb user=andym"
Result
FATAL:  no pg_hba.conf entry for host "123.123.123.123", user "andym", database "testdb"

The role does not exist (default role name from the OS user)

Shown as documented in the PostgreSQL documentation (Tutorial, Creating a Database). The client used the operating system user name as the role name because none was given. This example needs a running PostgreSQL server (a login over a Unix-domain socket), which PGlite does not provide, so it was not reproduced here.

-- As operating system user joe, with no database role named joe:
-- createdb mydb
Result
createdb: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: FATAL:  role "joe" does not exist

Peer authentication with a different operating system user

The documentation describes peer authentication (the OS user name must match the database role) but does not print this message, so the text is quoted from the PostgreSQL 18.6 source code; psql prints it after its "connection to server on socket ... failed:" prefix. This example needs a running PostgreSQL server (a local socket login with a peer rule), which PGlite does not provide, so it was not reproduced here.

-- pg_hba.conf has:  local  all  all  peer
-- As operating system user sara:
-- psql -U postgres
Result
FATAL:  Peer authentication failed for user "postgres"

How to prevent it

Manage pg_hba.conf as code: one narrow line per application (database, role, address range, scram-sha-256, hostssl where possible), reviewed and deployed with a check of pg_hba_file_rules for errors before the reload. When moving clients to new networks, add their ranges before the move.

Always pass the role and database explicitly in connection strings instead of relying on the operating system user name, and keep group roles NOLOGIN with members that log in.

Common questions

How do I fix "no pg_hba.conf entry for host" in PostgreSQL?

Add a pg_hba.conf line that matches the connection type, database, role and the client address shown in the message, with a password method such as scram-sha-256, then reload the configuration. If the message ends with "no encryption" and your lines are hostssl, connect with sslmode=require instead.

I edited pg_hba.conf but still get the error. Why?

The server reads the file only at start or on a reload (pg_ctl reload or SELECT pg_reload_conf()). Also check pg_hba_file_rules for a syntax error on the new line, and make sure no earlier line matches first.

What does "Peer authentication failed for user" mean?

A local peer rule matched, and your operating system user name is not the database role you asked for. Run psql as the matching OS user, add a pg_ident.conf map, or connect over TCP with -h localhost so a password rule applies.

Is "role does not exist" at login the same as 42704?

No. At login, a missing role is reported as FATAL with SQLSTATE 28000 and the connection is closed. Inside a session, statements such as GRANT or DROP ROLE that name a missing role raise a normal ERROR with SQLSTATE 42704.

Learn more on CodeWithSQL

Official documentation

Last technically reviewed 24 October 2026; examples and diagnostics run on PostgreSQL 18.6 documentation; SQL-level parts in PGlite 0.5.11. SQL-level examples were run in PGlite (PostgreSQL compiled to WebAssembly); examples that need a running server are shown as documented in the PostgreSQL documentation.

Still stuck on a PostgreSQL error?

Browse the full PostgreSQL error library, or get hands-on help from an experienced SQL professional.