How to fix Role already exists in PostgreSQL

PostgreSQLINTERMEDIATEMEDIUMUpdated Dec 29, 2025· 238 views

This error occurs when you attempt to create a PostgreSQL role (user account) that already exists in the database. Unlike CREATE TABLE, CREATE ROLE has no IF NOT EXISTS clause, so duplicate attempts fail. There are several solutions using PL/pgSQL blocks or conditional checks.

Quick fix

Fixes Role already exists

sudo -u postgres psql -c "\\du"
  1. Check if the role exists before creating
  2. Use a PL/pgSQL DO block with exception handling
  3. Use a conditional existence check in PL/pgSQL
  4. Modify an existing role using ALTER instead of CREATE
postgresql — error
sudo -u postgres psql -c "\\du"
Role already exists

What this error means

PostgreSQL manages database access through roles, which can be users (with login privileges) or groups. When you execute a CREATE ROLE statement, PostgreSQL checks its system catalog to ensure the role name is unique. If a role with that name already exists, the statement fails immediately. This is a schema-level constraint to prevent duplicate role definitions.

Typical symptoms

  • CREATE ROLE command fails with 'Role already exists' error
  • Migration scripts or initialization routines fail during database setup
  • Attempting to re-run creation scripts that worked previously now fail
  • pg_restore or psql -f dump_file commands fail when importing database definitions
  • CI/CD pipelines fail when idempotent role creation is attempted

Common causes

  1. The role was already created in a previous run or by another administrator
  2. Running the same CREATE ROLE script multiple times without checking for existence
  3. Restoring a database dump that contains roles that already exist in the target database
  4. Multiple scripts or tools attempting to create the same role concurrently
  5. Copying role creation code from another database without verifying the target state

How to fix "Role already exists"

1Check if the role exists before creating

First, verify whether the role already exists in your PostgreSQL instance:

bash
sudo -u postgres psql -c "\\du"

Or query directly:

sql
SELECT rolname FROM pg_roles WHERE rolname = 'my_user';

If the role appears in the results, it already exists and doesn't need to be created.

2Use a PL/pgSQL DO block with exception handling

Wrap your CREATE ROLE statement in an anonymous code block that catches the duplicate_object exception:

sql
DO $$
BEGIN
  CREATE ROLE my_user LOGIN PASSWORD 'my_password';
EXCEPTION
  WHEN duplicate_object THEN
    RAISE NOTICE 'Role my_user already exists, skipping.';
END
$$;

This approach allows the script to continue even if the role exists. The WHEN duplicate_object clause catches the duplicate error and simply logs a notice instead of failing.

3Use a conditional existence check in PL/pgSQL

For more control, check the pg_roles catalog before attempting creation:

sql
DO $$
BEGIN
  IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'my_user') THEN
    CREATE ROLE my_user LOGIN PASSWORD 'my_password';
    RAISE NOTICE 'Role my_user created.';
  ELSE
    RAISE NOTICE 'Role my_user already exists.';
  END IF;
END
$$;

This gives you visibility into whether the role was created or already existed.

4Modify an existing role using ALTER instead of CREATE

If the role exists and you need to change its properties, use ALTER ROLE instead:

sql
ALTER ROLE my_user WITH LOGIN PASSWORD 'new_password';

You can change login privileges, password, superuser status, and other attributes without recreating the role. Check the existing role first:

sql
SELECT * FROM pg_roles WHERE rolname = 'my_user';
5For database dumps and restores

When working with pg_dump, you have options to handle existing roles:

Option 1: Drop existing roles before restoring

bash
psql -U postgres -d your_database -c "DROP ROLE IF EXISTS my_user;"
psql -U postgres -d your_database -f dump.sql

Option 2: Dump without role definitions

bash
pg_dump --no-owner --no-acl source_db > dump.sql

Then roles must exist before you restore:

bash
psql -U postgres -d target_db -f dump.sql

Option 2 is safer for production environments where role management is separate from object ownership.

Advanced notes

Race Conditions: If multiple connections attempt to create the same role simultaneously, one succeeds and others hit the duplicate error. The exception handling approach is safer because it checks and creates in a single atomic transaction.

Idempotent Scripts: For infrastructure-as-code, use the DO block with exception handling approach. This makes scripts idempotent—they can be run repeatedly without side effects, which is important for Kubernetes, Terraform, or other declarative tools.

Cascade Drops: If you need to drop and recreate a role that owns objects, use DROP ROLE IF EXISTS my_user CASCADE; to remove dependent objects first. However, this is destructive and should only be used in development or with explicit intent.

Role Attributes: When creating or modifying a role, consider which privileges it needs: LOGIN (to connect), CREATEDB, CREATEROLE, SUPERUSER, REPLICATION, etc. Different attributes affect how the role can be used throughout your PostgreSQL instance.

Frequently asked questions

What does "Role already exists" mean?
PostgreSQL manages database access through roles, which can be users (with login privileges) or groups. When you execute a CREATE ROLE statement, PostgreSQL checks its system catalog to ensure the role name is unique. If a role with that name already exists, the statement fails immediately.
How do I fix "Role already exists"?
This error occurs when you attempt to create a PostgreSQL role (user account) that already exists in the database. Unlike CREATE TABLE, CREATE ROLE has no IF NOT EXISTS clause, so duplicate attempts fail. There are several solutions using PL/pgSQL blocks or conditional checks.
What causes "Role already exists"?
The role was already created in a previous run or by another administrator Running the same CREATE ROLE script multiple times without checking for existence Restoring a database dump that contains roles that already exist in the target database
Is the "Role already exists" error serious?
It is a medium-severity error — more of a blocker than a risk. The steps above resolve it.

Official resources & further reading