DEV Community

Cover image for Fix PostgreSQL Server Won't Start on Mac OS X (2026)
Mahdi BEN RHOUMA
Mahdi BEN RHOUMA

Posted on Originally published at iloveblogs.blog

Fix PostgreSQL Server Won't Start on Mac OS X (2026)

"How can I start PostgreSQL server on Mac OS X" — the exact commands that work

I hit this wall the first time I installed PostgreSQL through Homebrew on a fresh Mac. The package installed without errors, but when I tried to connect with psql, I got "connection refused." Running pg_ctl start threw back "pg_ctl: no database directory specified and no PGDATA environment variable." The fix is straightforward once you know which init system your installation uses: if you installed with Homebrew, use brew services start postgresql@16. If you used Postgres.app, start it from the Applications folder. If you built from source or used the EnterpriseDB installer, you need pg_ctl with the -D flag pointing at your data directory. I'll walk through every variant so you can pick the one that matches your setup.

  • Symptom: psql connection refused, pg_ctl: no database directory specified, or PostgreSQL simply not running after install
  • Root cause: PostgreSQL was installed but never started, or the init system (launchd / brew services) doesn't know where the data directory lives
  • Fix: brew services start postgresql@16 for Homebrew; pg_ctl -D /path/to/data start for manual installs; launch Postgres.app for the GUI option
  • Verification: pg_isready returns "accepting connections" or brew services list shows "started"

What you'll see

When PostgreSQL isn't running, you'll encounter one of these symptoms depending on what you try:

Trying to connect with psql:

psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such file or directory
        Is the server running locally and accepting connections on that socket?
Enter fullscreen mode Exit fullscreen mode

Trying to start manually with pg_ctl:

pg_ctl: no database directory specified and no PGDATA environment variable
Try "pg_ctl --help" for more information.
Enter fullscreen mode Exit fullscreen mode

Or, if you try brew services list and see:

postgresql@16  none
Enter fullscreen mode Exit fullscreen mode

It happens right after a fresh install, after a macOS upgrade, or after a reboot if the service wasn't configured to launch at startup. The behavior is the same across macOS Ventura, Sonoma, and Sequoia — the underlying issue is always that the PostgreSQL server process isn't running.

Why PostgreSQL doesn't auto-start on macOS

macOS doesn't know you installed PostgreSQL. Unlike Linux distributions that wire up systemd units during package installation, Homebrew on macOS gives you the binaries and leaves the service management to you. There are three layers at play here, and missing any one of them means PostgreSQL stays dead.

First, PostgreSQL itself needs an initialized data directory. Homebrew runs initdb for you during installation, creating the cluster at /opt/homebrew/var/postgresql@16 on Apple Silicon or /usr/local/var/postgresql@16 on Intel Macs. If you installed through a different method — the EnterpriseDB graphical installer, Postgres.app, or compiling from source — that directory lives somewhere else, and PostgreSQL has no way to guess where.

Second, macOS uses launchd as its service manager. Homebrew integrates with launchd through brew services, which writes a .plist file to ~/Library/LaunchAgents/. That plist tells launchd what binary to run, what arguments to pass, and whether to restart on failure. If you never ran brew services start, that plist either doesn't exist or exists but isn't loaded.

Third, the PGDATA environment variable is not set by default. When you run pg_ctl start without -D, PostgreSQL looks for PGDATA in your shell environment. It's not there unless you added it to your .zshrc or .bash_profile manually. That's why the "no database directory specified" error is so common — it's not a bug, it's PostgreSQL telling you it needs one piece of information you haven't given it.

The fix: start PostgreSQL with the method that matches your install

The command you run depends entirely on how PostgreSQL got onto your Mac. Here's the decision tree.

If you installed with Homebrew (most common)

Find your installed version first:

brew list --versions | grep postgresql
Enter fullscreen mode Exit fullscreen mode

You'll see something like postgresql@16 16.4. Then start the service:

brew services start postgresql@16
Enter fullscreen mode Exit fullscreen mode

Expected output:

==> Successfully started `postgresql@16` (label: homebrew.mxcl.postgresql@16)
Enter fullscreen mode Exit fullscreen mode

To have it start automatically on every reboot, that single command is enough — brew services writes the launchd plist and loads it immediately. No separate enable step is needed.

If you used Postgres.app

Postgres.app is a self-contained application bundle. Start it by opening the app from /Applications/Postgres.app. It adds an elephant icon to your menu bar. Click the icon, and you'll see "Start" if the server isn't running. Once started, it also configures your $PATH so psql works from the terminal — but you may need to restart your terminal or source the path changes.

If you installed via the EnterpriseDB installer or compiled from source

You need to know where your data directory is. Common locations:

  • EnterpriseDB: /Library/PostgreSQL/16/data
  • Source build (default): /usr/local/pgsql/data

Start with:

pg_ctl -D /Library/PostgreSQL/16/data start
Enter fullscreen mode Exit fullscreen mode

If you get a permissions error, the data directory is owned by the postgres user that the installer created. Switch to that user:

sudo -u postgres pg_ctl -D /Library/PostgreSQL/16/data start
Enter fullscreen mode Exit fullscreen mode

If you don't know where your data directory is

Search for it:

sudo find / -name "pg_hba.conf" 2>/dev/null
Enter fullscreen mode Exit fullscreen mode

The directory containing pg_hba.conf is your data directory. On my Apple Silicon Mac with Homebrew, that returns:

/opt/homebrew/var/postgresql@16/pg_hba.conf
Enter fullscreen mode Exit fullscreen mode

So the data directory is /opt/homebrew/var/postgresql@16.

Verify the fix

Run pg_isready — it's the simplest check and ships with every PostgreSQL installation:

pg_isready
Enter fullscreen mode Exit fullscreen mode

If PostgreSQL is running and accepting connections, you'll see:

/opt/homebrew/var/postgresql@16:5432 - accepting connections
Enter fullscreen mode Exit fullscreen mode

If it's not running:

/opt/homebrew/var/postgresql@16:5432 - no response
Enter fullscreen mode Exit fullscreen mode

For Homebrew specifically, confirm the service status:

brew services list
Enter fullscreen mode Exit fullscreen mode

Look for your PostgreSQL version in the output:

postgresql@16  started         mahdi ~/Library/LaunchAgents/homebrew.mxcl.postgresql@16.plist
Enter fullscreen mode Exit fullscreen mode

The "started" status means launchd has the process running and will restart it if it crashes. "none" means the service isn't loaded at all. "error" means launchd tried to start it but the process exited — check the logs with brew services info postgresql@16 to see the last exit code and log file path.

Finally, connect with psql to confirm you can actually run queries:

psql -U postgres -c "SELECT version();"
Enter fullscreen mode Exit fullscreen mode

Expected output:

                                                          version
---------------------------------------------------------------------------------------------------------------------------
 PostgreSQL 16.4 (Homebrew) on aarch64-apple-darwin23.6.0, compiled by Apple clang version 15.0.0, 64-bit
(1 row)
Enter fullscreen mode Exit fullscreen mode

Two variants that still trip people up

Variant A — "Is the server running?" after a macOS upgrade

macOS upgrades sometimes clear LaunchAgents or change permissions on the data directory. After upgrading to a new major macOS version, you might find brew services list shows your PostgreSQL service as "started" but pg_isready says "no response."

The fix: restart the service so launchd re-registers it under the new OS version:

brew services restart postgresql@16
Enter fullscreen mode Exit fullscreen mode

If that still fails, check the log file. Homebrew logs to ~/Library/Logs/Homebrew/postgresql@16.log by default. A common post-upgrade error is a permissions mismatch on the data directory. Fix it by reassigning ownership:

sudo chown -R $(whoami) /opt/homebrew/var/postgresql@16
Enter fullscreen mode Exit fullscreen mode

Variant B — Port conflict with another PostgreSQL instance

If you have both Postgres.app and Homebrew's PostgreSQL installed, or if you upgraded PostgreSQL versions and the old one is still running, you'll get a port conflict. The error looks like:

pg_ctl: could not start server
Examine the log output.
Enter fullscreen mode Exit fullscreen mode

And the log contains:

FATAL:  lock file "postmaster.pid" already exists
HINT:  Is another postmaster (PID 1234) running on port 5432?
Enter fullscreen mode Exit fullscreen mode

Find what's already on port 5432:

lsof -i :5432
Enter fullscreen mode Exit fullscreen mode

Kill the conflicting process or stop the other service:

brew services stop postgresql@15   # if you upgraded from 15 to 16
Enter fullscreen mode Exit fullscreen mode

Then start the version you want. If you need both versions running simultaneously, configure one to use a different port — I cover changing the PostgreSQL port in the PostgreSQL SHOW TABLES / DESCRIBE TABLE guide, where I walk through postgresql.conf edits.

Keep PostgreSQL running across reboots

The brew services start command handles this automatically — it writes a launchd plist that loads at login. But if you ever need to check or manually manage the plist, it lives at:

cat ~/Library/LaunchAgents/homebrew.mxcl.postgresql@16.plist
Enter fullscreen mode Exit fullscreen mode

The key fields are RunAtLoad (set to true so it starts at boot) and KeepAlive (set to true so launchd restarts it if it crashes). You can disable auto-start without uninstalling:

brew services stop postgresql@16
Enter fullscreen mode Exit fullscreen mode

This unloads the service but leaves the plist in place. To re-enable:

brew services start postgresql@16
Enter fullscreen mode Exit fullscreen mode

If you ever need to completely remove the service definition, brew services cleanup will delete plists for formula versions that are no longer installed.

For manual pg_ctl users, you can write your own launchd plist or add an alias to your shell config. I prefer the alias approach because it's explicit — I know exactly when PostgreSQL starts:

alias pgstart='pg_ctl -D /opt/homebrew/var/postgresql@16 -l ~/pg.log start'
alias pgstop='pg_ctl -D /opt/homebrew/var/postgresql@16 stop'
Enter fullscreen mode Exit fullscreen mode

Add those to ~/.zshrc, then source ~/.zshrc. Now pgstart and pgstop work from any terminal.

FAQ

How do I start PostgreSQL after installing it with Homebrew?

Run brew services start postgresql@16 (replace 16 with your installed version — check with brew list --versions | grep postgresql). This uses launchd to start PostgreSQL and keep it running across reboots. Verify with brew services list to confirm the service status shows "started." If you haven't initialized a database cluster yet, Homebrew does that automatically during installation, but if you skipped it or need to reinitialize, run initdb /opt/homebrew/var/postgresql@16 first.

Why does pg_ctl say "no database directory specified"?

PostgreSQL needs to know where its data directory lives. If you installed via Homebrew, the data directory is typically at /opt/homebrew/var/postgresql@16 on Apple Silicon or /usr/local/var/postgresql@16 on Intel Macs. Set the PGDATA environment variable in your shell config (export PGDATA=/opt/homebrew/var/postgresql@16 in ~/.zshrc) or pass -D /path/to/data explicitly to pg_ctl. If you're unsure where your data directory is, search for pg_hba.conf — the directory containing that file is your data directory.

How do I check which version of PostgreSQL I'm running?

Run psql --version from the terminal or connect and run SELECT version();. If psql isn't found, you may need to install the client tools first — I cover that exact scenario in Fix: psql: command not found. For a deeper dive into version checking methods, including how to query the server version remotely, see Which version of PostgreSQL am I running?.

Can I have multiple PostgreSQL versions installed on the same Mac?

Yes. Homebrew supports this with versioned formulae (postgresql@14, postgresql@15, postgresql@16). Each version gets its own data directory and runs on a different port by default — 5432, 5433, 5434, and so on. Start them independently with brew services start postgresql@14 and brew services start postgresql@16. To connect to a specific version, specify the port: psql -p 5433 -U postgres. If you need to change a user's password across versions, I've documented the exact ALTER ROLE syntax in How to Change a PostgreSQL User Password.

Related


Originally published at https://www.iloveblogs.blog

Top comments (0)