Skip to content
Troubleshooting

Odoo psycopg2.OperationalError: Role Does Not Exist

2026-07-25 · 8 min read

Last updated: 2026-08-09

psycopg2.OperationalError: FATAL:  role "odoo" does not exist

Short answer: the PostgreSQL role (user) that your Odoo config file expects to connect as was never created on this server, or was created under a different name than what's in odoo.conf. This is a PostgreSQL user/role problem, not a database or filestore problem, the database itself may be completely fine.

Causes, ranked

1. Fresh server, PostgreSQL role never created

Very common on a freshly provisioned server where PostgreSQL was installed but the Odoo-specific role setup step was skipped or failed silently. Check what roles actually exist:

sudo -u postgres psql -c "\du"

If there's no role matching your db_user setting, that's confirmed as the cause. This is the single most common way we see this error in practice: a fresh Ubuntu install where apt install postgresql was run, which creates only the default postgres superuser role, and the separate step of creating an odoo role was either skipped entirely in a rushed setup, or was run once against the wrong PostgreSQL cluster on a server with more than one cluster installed side by side from a prior OS or PostgreSQL upgrade.

2. Mismatch between odoo.conf's db_user and the actual role name

grep db_user /etc/odoo/odoo.conf

Compare this exactly against the role list from the command above. A common variant of this mistake: the role exists as odoo17 from a previous version's setup, but the config still says odoo.

3. Restoring a database dump onto a new server without recreating the role

A pg_dump/pg_restore migrates the database's data and schema, but if you're setting up PostgreSQL fresh on a new target server, the role the original server used has to be recreated separately, it isn't bundled inside a plain data dump by default.

4. Role exists but under a different case or with a typo

PostgreSQL role names are case-sensitive when quoted. Odoo and odoo are different roles if either was created with quotes. Check for this specifically if the role list from step 1 looks right at a glance but the error persists.

# List roles with exact casing visible
sudo -u postgres psql -c "SELECT rolname FROM pg_roles;"

The plain \du output can visually blur case differences depending on your terminal font, the SELECT rolname FROM pg_roles query gives you the exact stored string with no ambiguity.

5. pg_hba.conf authentication method mismatch

A related but distinct error worth ruling out separately: if the role does exist and the name matches exactly, but you're still failing to connect, check whether the actual error is really "role does not exist" or a different authentication failure that superficially looks similar in the logs. Confirm PostgreSQL's pg_hba.conf allows the connection method Odoo is using (commonly md5 or scram-sha-256 for password auth, or peer for local Unix-socket auth matching the OS user):

sudo cat /etc/postgresql/*/main/pg_hba.conf | grep -v "^#" | grep -v "^$"

If you're connecting over peer authentication, the PostgreSQL role name must match the connecting OS user's name exactly, this is a separate and common source of confusion from the role simply not existing at all.

6. Odoo running under Docker with the wrong host in db_host

In containerised setups, a "role does not exist" error can actually mask a "connected to the wrong PostgreSQL instance entirely" problem. If db_host in your config resolves to a different container or a stale DNS entry than the one where you actually created the role, you'll get exactly this error even though the role exists correctly on the PostgreSQL instance you meant to use. Confirm you're checking roles on the same instance Odoo is actually connecting to:

docker exec -it your_postgres_container psql -U postgres -c "\du"

The fix

# Create the missing role, matching exactly what odoo.conf expects
sudo -u postgres createuser -s odoo

# Or, if you need a password-authenticated role rather than peer/trust auth
sudo -u postgres psql -c "CREATE ROLE odoo WITH LOGIN PASSWORD 'a_real_password' SUPERUSER;"

# Confirm it now exists
sudo -u postgres psql -c "\du" | grep odoo

Odoo's own database role is commonly given SUPERUSER in simple single-server setups since it needs to create and drop databases for multi-tenant installs. For a hardened production setup with a fixed single database, a more restricted role with explicit CREATEDB only is worth considering, but that's a deliberate hardening decision, not the default fix for this specific error.

If the goal is a narrower production role rather than a full superuser, this is a working minimal grant for a single fixed database, once that database already exists and doesn't need to be created or dropped by the Odoo role itself:

sudo -u postgres psql -c "CREATE ROLE odoo WITH LOGIN PASSWORD 'a_real_password';"
sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE your_db TO odoo;"
sudo -u postgres psql -d your_db -c "GRANT ALL ON ALL TABLES IN SCHEMA public TO odoo;"
sudo -u postgres psql -d your_db -c "GRANT ALL ON ALL SEQUENCES IN SCHEMA public TO odoo;"

Test this narrower grant against a staging copy before applying it to production, some Odoo modules or upgrade scripts do expect CREATEDB or SUPERUSER at specific points (module installation, database duplication features in the UI), and a role that's too narrow will surface as a different, more confusing permissions error later rather than this one.

How to verify

sudo systemctl restart odoo
sudo journalctl -u odoo -n 30 --no-pager
# confirm no further OperationalError, and a normal startup log

Also confirm Odoo can actually list databases through the web UI's database selector, that exercises the same connection path end to end.

Still stuck

If the role exists and matches exactly but the error persists, work through these:

  • pg_hba.conf authentication method mismatch. A role can exist correctly and still be rejected if the auth method (peer vs md5 vs trust) doesn't match how Odoo is actually connecting (unix socket vs TCP with a password). Confirm the entry order in pg_hba.conf too, PostgreSQL uses the first matching line, so a broader rule earlier in the file can shadow a more specific one you added below it.
  • PostgreSQL not actually restarted after a config change. Both pg_hba.conf and role changes made via ALTER ROLE in some setups require a reload, not necessarily a full restart, but if you're unsure, sudo systemctl reload postgresql is safe to run and confirms the running config matches the file on disk.
  • Wrong PostgreSQL cluster on a multi-version server. Servers that have been upgraded across PostgreSQL major versions sometimes end up running two clusters simultaneously (14 and 16, for example) on different ports. Confirm db_port in odoo.conf and which cluster's pg_hba.conf you actually edited: sudo pg_lsclusters.
  • Environment variables overriding the config file. If Odoo is started via a systemd unit or Docker entrypoint that sets PGUSER, PGHOST or similar environment variables, those can silently override what's written in odoo.conf. Check the actual unit file or container entrypoint, not just the config file, if the values still don't seem to be taking effect after a fix.

Sources: PostgreSQL CREATE ROLE documentation, PostgreSQL pg_hba.conf documentation.

Talal Yousaf, Senior DevOps Engineer at DevFusion Tech. 70+ Odoo deployments across Community and Enterprise, versions 13 through 19. More about DevFusion · LinkedIn

Published 2026-07-25 · updated 2026-08-09

ShareLinkedInXWhatsApp

Hit the same wall in production?

Tell us what you're running and where it breaks. A 30 minute call, no pitch deck, and a straight answer on whether we can help.