How to Fix PostgreSQL Startup Issues on macOS

Encountering difficulties when attempting to start the PostgreSQL server on macOS is a common scenario, particularly after a fresh installation, system update, or unexpected shutdown.

Symptoms often include connection failures from applications (e.g., Ruby on Rails reporting “Is the server running on host ‘localhost’ and accepting TCP/IP connections on port 5432?”) and status commands like pg_ctl status indicating “no server running,” even after attempting a start command.

This guide explores the common underlying causes for these startup failures on macOS and outlines various methods to diagnose and resolve them, based on typical configurations and practices.

Understanding the Core Issues

Several factors can prevent PostgreSQL from starting correctly on a macOS system. Identifying the root cause is key to applying the right solution.

  • Missing Database Initialization: A frequent oversight, especially after manual or Homebrew installations, is failing to initialize the PostgreSQL database cluster using the initdb command. This command sets up the necessary directory structure and template databases.
  • Configuration File Problems: PostgreSQL relies on configuration files like postgresql.conf (for server settings like listen addresses and port) and pg_hba.conf (for client authentication rules). If these files are missing (only sample files like *.conf.sample exist) or incorrectly configured, the server may fail to start or refuse connections.
  • Incorrect Permissions: The data directory (commonly /usr/local/var/postgres for Homebrew installs) requires specific permissions (typically 0700, meaning only the owner has read, write, and execute permissions). Incorrect permissions can lead to a fatal error during startup.
  • Missing Log File or Directory: The server might be configured to write logs to a specific file (e.g., server.log) within the data directory. If this file or its parent directory doesn’t exist, startup can fail.
  • Stale PID File: After an abrupt system shutdown or crash, a postmaster.pid file might remain in the data directory. This file normally indicates a running server, and its presence can prevent a new instance from starting.
  • Incorrect User Execution: Attempting to start the server directly as the root user using sudo pg_ctl start will fail. PostgreSQL requires running under an unprivileged user account (often postgres or the user who installed it).
  • Installation Method Conflicts or Versioning Issues: How PostgreSQL was installed (Homebrew, MacPorts, EnterpriseDB installer, Postgres.app, .dmg) dictates the correct start/stop procedures and file paths. Using commands intended for a different installation method won’t work. Additionally, if specific versions are installed (e.g., via Homebrew with @version), commands must often include that version specifier.

PostgreSQL Startup Issues on macOS

Read: How to Upgrade Node.js on macOS

Solutions for Starting PostgreSQL

Based on the potential causes, several methods exist to start the PostgreSQL server on macOS.

1. Ensure Database Cluster is Initialized

If the database cluster hasn’t been created, PostgreSQL cannot start. This is often the primary issue after installation.

Run the initdb command, specifying the data directory path (adjust path if necessary):

initdb /usr/local/var/postgres -E utf8

If a data directory exists but seems problematic, you might need to remove or rename it before running initdb (use caution, this removes existing data):

# Optional: Back up existing data first
mv /usr/local/var/postgres /usr/local/var/postgres.backup

# Or, remove existing directory (DATA LOSS!)
rm -rf /usr/local/var/postgres

# Then initialize
initdb /usr/local/var/postgres -E utf8

Some setups might use a `data` subdirectory within the main path:

# Example for alternative path structure
initdb `brew --prefix`/var/postgres/data -E utf8

2. Manual Start/Stop using pg_ctl

The pg_ctl utility is the standard command-line tool for controlling a PostgreSQL server.

To start the server, specifying the data directory (-D) and optionally a log file (-l):

pg_ctl -D /usr/local/var/postgres -l /usr/local/var/postgres/server.log start

If the log file or directory doesn’t exist, you may need to create it first:

mkdir -p /usr/local/var/postgres
touch /usr/local/var/postgres/server.log
# Or use: vi /usr/local/var/postgres/server.log

To stop the server:

pg_ctl -D /usr/local/var/postgres stop

Or perform a faster shutdown:

pg_ctl -D /usr/local/var/postgres stop -s -m fast

Important: Do not run pg_ctl start directly with sudo. If permissions require elevation, use sudo -u :

# Example for EnterpriseDB or similar installs where 'postgres' user exists
sudo -u postgres pg_ctl -D /Library/PostgreSQL/[VERSION]/data start
sudo -u postgres pg_ctl -D /Library/PostgreSQL/[VERSION]/data stop

EnterpriseDB installation (default in /Library/PostgreSQL) : Blue for directories, Black for regular files, Red for critical files,
Purple for configuration files

For installations directly from the Mac package (.dmg):

sudo su postgres
/Library/PostgreSQL/[VERSION]/bin/pg_ctl -D /Library/PostgreSQL/[VERSION]/data start # or stop

Aliases can simplify these commands (add to ~/.bash_profile or ~/.zshrc):

alias pg-start='pg_ctl -D /usr/local/var/postgres -l /usr/local/var/postgres/server.log start'
alias pg-stop='pg_ctl -D /usr/local/var/postgres stop -s -m fast'
# For sudo -u alias:
# alias postgres.server="sudo -u postgres pg_ctl -D /Library/PostgreSQL/[VERSION]/data"
# Usage: postgres.server start / postgres.server stop

Homebrew installation (default location in /usr/local) : Blue for directories, Black for regular files, Red for critical files,
Purple for configuration files

Read: How to Fix `dyld: Library not loaded: icu4c` Errors on macOS After Homebrew Operations

3. Using Homebrew Services

For installations managed by Homebrew, the brew services command provides a simpler interface to manage PostgreSQL as a background service.

To start the service (automatically handles log files and data directory if defaults are used):

brew services start postgresql

To stop the service:

brew services stop postgresql

To restart the service:

brew services restart postgresql

If you installed a specific version (e.g., version 10 or 14):

brew services start postgresql@10
brew services stop postgresql@14

Note: brew services start configures PostgreSQL to start automatically at login. If brew services fails silently, ensure initdb has been run successfully first.

4. Using launchctl (Homebrew)

Homebrew installations also provide launchd plist files for managing the service directly with macOS’s native service manager.

To load (start) the service:

launchctl load ~/Library/LaunchAgents/homebrew.mxcl.postgresql.plist

To unload (stop) the service:

launchctl unload ~/Library/LaunchAgents/homebrew.mxcl.postgresql.plist

Symlinking the plist file enables automatic start at login:

ln -sfv /usr/local/opt/postgresql/*.plist ~/Library/LaunchAgents

5. Removing Stale postmaster.pid File

If the server failed to start after an improper shutdown, a leftover PID file might be the cause.

Locate and remove the postmaster.pid file from the data directory:

# Common location for Homebrew installs
rm /usr/local/var/postgres/postmaster.pid

# Example location for versioned Homebrew install
# rm /usr/local/var/postgresql@9.6/postmaster.pid

# Example location for Postgres.app install
# rm /Users/Library/Application\ Support/Postgres/var-/postmaster.pid

After removing the file, attempt to start the server using one of the methods above (e.g., brew services start postgresql or pg_ctl start).

Postgres.app installation (in /Applications with data in Application Support) : Blue for directories, Black for regular files, Red for critical files,
Purple for configuration files

6. Correcting Configuration Files

Ensure necessary configuration files exist and are readable.

If only *.sample files exist, copy them:

# Example paths, adjust based on your install location
cp /usr/local/Cellar/postgresql/[VERSION]/share/postgresql/postgresql.conf.sample /usr/local/var/postgres/postgresql.conf
cp /usr/local/Cellar/postgresql/[VERSION]/share/postgresql/pg_hba.conf.sample /usr/local/var/postgres/pg_hba.conf

Verify essential settings within the files, particularly listen_addresses and port in postgresql.conf, and connection rules in pg_hba.conf. For basic local access, ensure pg_hba.conf includes lines like:

# IPv4 local connections:
host    all             all             127.0.0.1/32           trust
# IPv6 local connections:
host    all             all             ::1/128                trust

7. Adjusting Data Directory Permissions

If log files indicate a permissions error (e.g., “FATAL: data directory … has group or world access”), correct the permissions.

Set permissions to owner-only access:

chmod 0700 /usr/local/var/postgres

8. Alternative Management Tools and Methods

  • Lunchy Gem: A wrapper for launchctl.
    # Assuming gem install lunchy completed
    lunchy start postgres  # or postgresql
    lunchy stop postgres   # or postgresql
  • Postgres.app: A standalone application providing a PostgreSQL server. Start/stop via the app interface or command line:
    # Start
    open -a Postgres
    
    # Stop (Note: killall can be abrupt)
    killall Postgres
    killall postgres
  • Running in Foreground (for testing): Start the server directly, logging to the console.
    # Assumes initdb has been run in the 'db' directory
    postgres -D db

    (Press Ctrl+C to stop).

  • MacPorts: Use the port load/unload commands.
    sudo port load postgresql-server
    sudo port unload postgresql-server
  • macOS Server.app: Use the serveradmin command.
    sudo serveradmin start postgres
    sudo serveradmin stop postgres
  • Force Stop (Use with caution): If the server is unresponsive.
    # Requires proctools (brew install proctools)
    sudo pkill -u postgres

9. Upgrading PostgreSQL and Database

Sometimes, issues arise after system updates or when using older versions. Upgrading via Homebrew might resolve underlying problems.

# Upgrade PostgreSQL package
brew upgrade postgresql

# After major version upgrades, database files might need upgrading
brew postgresql-upgrade-database

# Then attempt to start the service again
brew services restart postgresql

A simple stop/start cycle after potential upgrades can also help:

brew services stop postgresql
brew services start postgresql

PostgreSQL Startup Troubleshooting Checklist

Verification and Troubleshooting

After applying a potential solution, verify if the server is running:

  • Check process list: ps auxwww | grep postgres (Look for more than just the grep process itself).
  • Use pg_ctl status: pg_ctl -D /usr/local/var/postgres status.
  • Use brew services list: Check the status if using Homebrew services.
  • Check log files: Look for errors in /usr/local/var/postgres/server.log (or the configured log path). Use tail -f /usr/local/var/postgres/server.log to monitor logs in real-time. Adjust path for specific versions if needed (e.g., /usr/local/var/postgres@11/server.log).
  • Attempt connection: Use psql or your application to connect to the database (e.g., psql -d mydatabase).

Conclusion

Failure to start the PostgreSQL server on macOS often stems from incomplete initialization (missing initdb), configuration file issues, incorrect permissions, or stale process identifiers after unclean shutdowns.

Depending on the installation method (Homebrew, direct download, etc.), different commands like pg_ctl, brew services, or direct launchctl interactions are used for management. By systematically checking initialization status, configuration, permissions, and using the appropriate commands for the specific installation, most startup problems can be effectively resolved.

 

Akil Sharma

Akil is a dedicated Cybersecurity Analyst with a strong focus on both offensive and defensive security techniques across Linux and Windows platforms. He delves into topics like vulnerability assessment, penetration testing methodologies, malware analysis, incident response, and implementing security frameworks. Akil is committed to educating readers on the latest threats and sharing actionable strategies for hardening systems and protecting data.