How to fix Cannot be run as root in PostgreSQL
PostgreSQL intentionally refuses to run as the root user for security reasons. Switch to an unprivileged user (typically postgres) to start the database server successfully.
Quick fix
Fixes Cannot be run as root
su - postgres- Switch to the postgres system user before running commands
- Use sudo -u postgres to run individual commands
- Connect to an existing PostgreSQL database as postgres user
- Fix Docker configurations to use the postgres user
su - postgresCannot be run as root
What this error means
PostgreSQL enforces a critical security policy by refusing to execute as the root user. When you attempt to run pg_ctl, initdb, or the postmaster daemon as root, PostgreSQL detects this and immediately halts, returning the error "pg_ctl: cannot be run as root." This is not a bug or limitation—it is a deliberate design choice. Running a database server with root privileges creates a severe security vulnerability: if an attacker compromises PostgreSQL, they gain complete control over your entire system, including access to all files, user accounts, and system resources. PostgreSQL must be run by an unprivileged operating system user (conventionally named "postgres") to contain the blast radius of any potential breach.
Typical symptoms
- pg_ctl: cannot be run as root. Please log in (using, e.g., "su") as the (unprivileged) user that will own the server process
- initdb refuses to execute when run with sudo or as the root user
- PostgreSQL server fails to start when launched as root in Docker containers or VMs
- CI/CD pipelines fail during PostgreSQL initialization steps
Common causes
- Running pg_ctl, initdb, or postmaster directly as the root user
- Using sudo with PostgreSQL commands (sudo pg_ctl, sudo initdb) without switching to the postgres user first
- Containers or scripts configured to run PostgreSQL startup commands as root
- Insufficient understanding of PostgreSQL's security model and privilege separation
How to fix "Cannot be run as root"
The safest and most common approach is to switch to the postgres user before running any PostgreSQL commands. Use the su command with the - flag to get a login shell with the postgres user's environment:
su - postgresNow you can run PostgreSQL commands without sudo:
pg_ctl start -D /var/lib/postgresql/14/main
initdb -D /path/to/data/directoryYou can verify you're running as the correct user with whoami.
If you need to run PostgreSQL commands from a non-root user account, use sudo -u postgres to execute them as the postgres user without an interactive shell:
sudo -u postgres pg_ctl start -D /var/lib/postgresql/14/main
sudo -u postgres initdb -D /path/to/data/directory
sudo -u postgres psqlThis approach is convenient for one-off commands or scripts.
To connect to a running PostgreSQL server, use the postgres user directly:
sudo -u postgres psqlAlternatively, if you're already logged in as another user, specify the user with the -U flag:
psql -U postgresDo NOT attempt to connect as the root user—PostgreSQL won't recognize a root role unless explicitly created, which is extremely unusual.
If you're running PostgreSQL in a Docker container and hitting this error, update your Dockerfile or docker-compose.yml to ensure the postgres user is used. Example Dockerfile:
USER postgres
CMD ["postgres", "-D", "/var/lib/postgresql/data"]For docker-compose.yml, ensure the container is not running as root:
services:
postgres:
image: postgres:15
environment:
POSTGRES_PASSWORD: password
user: "999:999" # postgres UID:GIDAlways verify the official postgres Docker image documentation for best practices.
Advanced notes
PostgreSQL's refusal to run as root is a well-intentioned security boundary that cannot be bypassed. Some Linux distributions (like Debian/Ubuntu) create a dedicated "postgres" system user during installation with UID typically around 999. On macOS with Homebrew, this check is similarly enforced. In containerized environments, ensure your base image or init scripts properly switch to the postgres user before launching the daemon. If you're building a custom container, avoid using root as the default user; instead, create a non-root user and use the USER directive. SELinux or AppArmor policies may add additional restrictions, so consult your security policy if you encounter permission denials even when running as postgres.
Frequently asked questions
- What does "Cannot be run as root" mean?
- PostgreSQL enforces a critical security policy by refusing to execute as the root user. " This is not a bug or limitation—it is a deliberate design choice. Running a database server with root privileges creates a severe security vulnerability: if an attacker compromises PostgreSQL, they gain complete control over your entire system, including access to all files, user accounts, and system resources.
- How do I fix "Cannot be run as root"?
- PostgreSQL intentionally refuses to run as the root user for security reasons. Switch to an unprivileged user (typically postgres) to start the database server successfully.
- What causes "Cannot be run as root"?
- Running pg_ctl, initdb, or postmaster directly as the root user Using sudo with PostgreSQL commands (sudo pg_ctl, sudo initdb) without switching to the postgres user first Containers or scripts configured to run PostgreSQL startup commands as root
- Is the "Cannot be run as root" error serious?
- Yes. This is a high-severity error that usually blocks work until it is fixed, but the steps above resolve it.