Fix: PostgreSQL FATAL: role "username" does not exist
Quick Answer
How to fix PostgreSQL FATAL role does not exist error caused by missing database roles, peer authentication, wrong usernames, and platform-specific installation defaults.
The Error
You try to connect to PostgreSQL and get:
psql: error: connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed:
FATAL: role "ubuntu" does not existOr variations:
FATAL: role "root" does not existFATAL: role "myuser" does not existpsql: FATAL: role "postgres" does not existdjango.db.utils.OperationalError: FATAL: role "app_user" does not existPostgreSQL refused the connection because the database role (user) you are trying to authenticate as does not exist in the PostgreSQL server.
Why This Happens
PostgreSQL uses roles for authentication. Every connection must specify a role name. When you run psql without specifying a user, PostgreSQL defaults to your operating system username. If your OS username is ubuntu, root, or john, PostgreSQL looks for a role with that name — and if it doesn’t exist, you get this error.
Common causes:
- Running psql as your OS user without a matching role. Your OS user is
ubuntubut PostgreSQL only has thepostgresrole. - Fresh installation. PostgreSQL creates only the
postgressuperuser role by default. No other roles exist until you create them. - Wrong username in connection string. Your application’s
DATABASE_URLspecifies a role that was never created. - Docker container setup. The container only has the default role unless you configure
POSTGRES_USER. - Peer authentication. PostgreSQL is configured to match the OS username to the database role name, and they don’t match.
Fix 1: Connect as the postgres Superuser First
On most installations, the only role that exists initially is postgres. Connect as that user first:
sudo -u postgres psqlThis switches to the postgres OS user and runs psql, which connects as the postgres role via peer authentication.
Once connected, you can create the role you need:
CREATE ROLE myuser WITH LOGIN PASSWORD 'mypassword';Or with additional privileges:
CREATE ROLE myuser WITH LOGIN PASSWORD 'mypassword' CREATEDB;Then create a database for the user:
CREATE DATABASE mydb OWNER myuser;Exit with \q and connect as the new user:
psql -U myuser -d mydb -h localhostPro Tip: Using
-h localhostforces TCP/IP connection with password authentication, bypassing peer authentication. Without it, psql uses the Unix socket and peer auth, which requires the OS username to match the role name.
Fix 2: Create a Role Matching Your OS Username
If you want psql to work without specifying -U, create a role that matches your OS username:
# Check your OS username
whoami
# Output: ubuntu
# Create a matching role
sudo -u postgres createuser --interactive ubuntuThe --interactive flag prompts you for options:
Shall the new role be a superuser? (y/n) n
Shall the new role be allowed to create databases? (y/n) y
Shall the new role be allowed to create more new roles? (y/n) nThen create a database with the same name:
sudo -u postgres createdb ubuntuNow psql works without any flags:
psqlPostgreSQL defaults to your OS username for both the role and the database.
Fix 3: Fix the Connection String
If the error comes from an application, check the database connection string:
postgresql://myuser:mypassword@localhost:5432/mydbVerify that:
- The role
myuserexists — run\duin psql to list all roles. - The password is correct — reset it with
ALTER ROLE myuser WITH PASSWORD 'newpassword';. - The database
mydbexists — run\lin psql to list all databases.
Django settings.py:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'mydb',
'USER': 'myuser', # This role must exist
'PASSWORD': 'mypassword',
'HOST': 'localhost',
'PORT': '5432',
}
}Rails database.yml:
default: &default
adapter: postgresql
username: myuser # This role must exist
password: mypassword
host: localhostIf the connection itself fails before authentication, see Fix: PostgreSQL connection refused.
Fix 4: Fix pg_hba.conf Authentication
PostgreSQL’s pg_hba.conf file controls who can connect and how they authenticate. Common authentication methods:
| Method | How it works |
|---|---|
peer | OS username must match database role name |
md5 | Password authentication (hashed) |
scram-sha-256 | Password authentication (more secure) |
trust | No authentication (dangerous) |
ident | Like peer, but over TCP |
Find your pg_hba.conf:
sudo -u postgres psql -c "SHOW hba_file;"Common location: /etc/postgresql/16/main/pg_hba.conf
The peer authentication issue:
If pg_hba.conf has:
local all all peerThen every local connection requires the OS username to match the PostgreSQL role name. Either create a matching role (Fix 2) or change peer to md5 or scram-sha-256:
local all all scram-sha-256Reload PostgreSQL after editing:
sudo systemctl reload postgresqlCommon Mistake: Editing
pg_hba.confbut forgetting to reload PostgreSQL. The changes only take effect after a reload (systemctl reload) or restart (systemctl restart). A restart disconnects existing clients; a reload does not.
Fix 5: Fix Docker PostgreSQL Roles
In Docker, the default role is controlled by the POSTGRES_USER environment variable:
docker run -e POSTGRES_USER=myuser -e POSTGRES_PASSWORD=mypassword -e POSTGRES_DB=mydb -p 5432:5432 postgres:16If you omit POSTGRES_USER, the default role is postgres.
Docker Compose:
services:
db:
image: postgres:16
environment:
POSTGRES_USER: myuser
POSTGRES_PASSWORD: mypassword
POSTGRES_DB: mydb
ports:
- "5432:5432"Existing container with wrong role:
If the container was already created with a different user, the data volume retains the old configuration. Delete the volume and recreate:
docker compose down -v # -v removes volumes
docker compose up -dWarning: -v deletes all data in the PostgreSQL volume. Only do this for development databases.
If you need to add a role to an existing container:
docker exec -it my-postgres psql -U postgres -c "CREATE ROLE myuser WITH LOGIN PASSWORD 'mypassword';"
docker exec -it my-postgres psql -U postgres -c "CREATE DATABASE mydb OWNER myuser;"Fix 6: Fix macOS Homebrew PostgreSQL
Homebrew PostgreSQL on macOS creates a superuser role matching your macOS username automatically. But if you run psql as a different user or the role was deleted:
Check the default role:
whoami
# Output: john
psql -l # List databases — uses "john" as the roleIf the role was deleted or never created:
createuser --superuser $(whoami)
createdb $(whoami)If postgres role doesn’t exist (common with Homebrew):
createuser --superuser postgresHomebrew installs do not always create the postgres role, which trips up tutorials and tools that assume it exists.
Fix 7: Fix Role Permissions
After creating a role, you might need to grant it access to existing databases and schemas:
-- Connect as postgres superuser
sudo -u postgres psql
-- Grant connection to a database
GRANT CONNECT ON DATABASE mydb TO myuser;
-- Connect to the database
\c mydb
-- Grant usage on schema
GRANT USAGE ON SCHEMA public TO myuser;
-- Grant access to all existing tables
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO myuser;
-- Grant access to future tables
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO myuser;
-- Grant sequence usage (needed for auto-increment columns)
GRANT USAGE ON ALL SEQUENCES IN SCHEMA public TO myuser;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT USAGE ON SEQUENCES TO myuser;If the role exists but can’t see tables, the issue is schema permissions. This manifests as relation does not exist errors.
Fix 8: List and Manage Existing Roles
List all roles:
\duOr:
SELECT rolname, rolsuper, rolcreatedb, rolcreaterole, rolcanlogin
FROM pg_roles
ORDER BY rolname;Rename a role:
ALTER ROLE old_name RENAME TO new_name;Drop a role:
-- First reassign owned objects
REASSIGN OWNED BY old_role TO postgres;
-- Then drop
DROP ROLE old_role;You cannot drop a role that owns objects. Reassign or drop the owned objects first.
Grant superuser:
ALTER ROLE myuser WITH SUPERUSER;Remove superuser (for security):
ALTER ROLE myuser WITH NOSUPERUSER;Still Not Working?
If the role exists but you still get this error:
Check for case sensitivity. PostgreSQL folds unquoted identifiers to lowercase. If the role was created with double quotes (CREATE ROLE "MyUser"), you must always use quotes. Check with \du — the role name is shown exactly as stored.
Check the PostgreSQL port. If multiple PostgreSQL instances are running, you might be connecting to the wrong one:
psql -U myuser -h localhost -p 5432
psql -U myuser -h localhost -p 5433 # Another instanceCheck pg_ident.conf for ident mapping. If pg_hba.conf uses peer map=mymap, the pg_ident.conf file controls which OS users map to which database roles. An incorrect mapping causes this error.
Check for connection pooler interference. PgBouncer or Pgpool-II might authenticate against their own user list, not PostgreSQL’s. Check the pooler’s auth_file or userlist.txt.
Check if PostgreSQL is actually running:
systemctl status postgresqlIf the service is down, you get a connection error rather than a role error. But if a different database engine is running on the same port, you might get unexpected authentication errors.
If the connection itself fails rather than authentication, see Fix: PostgreSQL connection refused. If the role exists but queries fail because tables are missing, see Fix: relation does not exist.
For similar authentication issues in MySQL, see Fix: MySQL access denied for user.
Solo developer based in Japan. Every solution is cross-referenced with official documentation and tested before publishing.
Was this article helpful?
Related Articles
Fix: PostgreSQL ERROR: deadlock detected
How to fix PostgreSQL deadlock detected error caused by concurrent transactions, conflicting row locks, foreign key locks, and lock ordering issues.
Fix: PostgreSQL permission denied for table (or relation, schema, sequence)
How to fix the PostgreSQL error 'permission denied for table' by granting privileges, fixing default permissions, resolving schema and ownership issues, RLS policies, and role inheritance.
Fix: PostgreSQL ERROR: relation "table_name" does not exist
How to fix the PostgreSQL 'relation does not exist' error caused by schema search_path issues, case sensitivity, wrong database connections, missing migrations, and more.
Fix: PostgreSQL Connection Refused – Could Not Connect to Server
How to fix the PostgreSQL error 'could not connect to server: Connection refused' caused by server not running, wrong host/port, pg_hba.conf, or firewall issues.