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.
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.
First, verify whether the role already exists in your PostgreSQL instance:
sudo -u postgres psql -c "\\du"Or query directly:
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.
Wrap your CREATE ROLE statement in an anonymous code block that catches the duplicate_object exception:
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.
For more control, check the pg_roles catalog before attempting creation:
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.
If the role exists and you need to change its properties, use ALTER ROLE instead:
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:
SELECT * FROM pg_roles WHERE rolname = 'my_user';When working with pg_dump, you have options to handle existing roles:
Option 1: Drop existing roles before restoring
psql -U postgres -d your_database -c "DROP ROLE IF EXISTS my_user;"
psql -U postgres -d your_database -f dump.sqlOption 2: Dump without role definitions
pg_dump --no-owner --no-acl source_db > dump.sqlThen roles must exist before you restore:
psql -U postgres -d target_db -f dump.sqlOption 2 is safer for production environments where role management is separate from object ownership.
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.
ERROR: syntax error at end of input
Syntax error at end of input in PostgreSQL
Bind message supplies N parameters but prepared statement requires M
Bind message supplies N parameters but prepared statement requires M in PostgreSQL
Multidimensional arrays must have sub-arrays with matching dimensions
Multidimensional arrays must have sub-arrays with matching dimensions
ERROR: value too long for type character varying
Value too long for type character varying
insufficient columns in unique constraint for partition key
How to fix "insufficient columns in unique constraint for partition key" in PostgreSQL