Question

How to Fix PG::ConnectionBad: Connection Refused in Rails with PostgreSQL

rubyruby-on-railsdatabasepostgresqldatabase-connection

Question

When I run my Rails 4.0 server, I get a PostgreSQL connection error saying the connection was refused on localhost:5432.

The relevant error output is:

Started GET "/" for 127.0.0.1 at 2013-11-06 23:56:36 -0500

PG::ConnectionBad - could not connect to server: Connection refused
Is the server running on host "localhost" (::1) and accepting
TCP/IP connections on port 5432?
could not connect to server: Connection refused
Is the server running on host "localhost" (127.0.0.1) and accepting
TCP/IP connections on port 5432?
could not connect to server: Connection refused
Is the server running on host "localhost" (fe80::1) and accepting
TCP/IP connections on port 5432?

My database.yml looks like this:

development:
  adapter: postgresql
  encoding: unicode
  database: metals-directory_development
  pool: 5
  username:
  password:
  template: template0
  host: localhost
  port: 5432

test: &test
  adapter: postgresql
  encoding: unicode
  database: metals-directory_test
  pool: 5
  username:
  password:
  template: template0
  host: localhost
  port: 5432

staging:
  adapter: postgresql
  encoding: unicode
  database: metals-directory_production
  pool: 5
  username:
  password:
  template: template0
  host: localhost

production:
  adapter: postgresql
  encoding: unicode
  database: metals-directory_production
  pool: 5
  username:
  password:
  template: template0
  host: localhost

cucumber:
  <<: *test

I am using macOS Mavericks (OS X 10.9). I have already tried reinstalling both PostgreSQL and the pg gem several times. What does this error actually mean, and how can I diagnose and fix it in a Rails app using PostgreSQL?

Short Answer

By the end of this page, you will understand what PG::ConnectionBad with connection refused means in Rails, how Rails uses database.yml to connect to PostgreSQL, and how to systematically check whether PostgreSQL is running, listening on the expected port, and configured correctly for your app.

Concept

PG::ConnectionBad is a PostgreSQL connection error raised by the Ruby pg driver when Rails cannot open a database connection.

In this specific case, connection refused usually means:

  • Rails successfully tried to reach the machine and port you specified.
  • But nothing was accepting connections there.
  • In other words, PostgreSQL is likely not running, not listening on that host/port, or your Rails config points to the wrong place.

This is different from other database errors:

  • authentication failed → PostgreSQL is running, but username/password is wrong.
  • database does not exist → PostgreSQL is running, but the named database has not been created.
  • could not translate host name → the hostname itself is invalid.
  • connection refused → the service is not available at that address and port.

In Rails, the connection details typically come from config/database.yml:

  • adapter: which database system to use
  • database: the database name
  • username / password: login credentials
  • host: where PostgreSQL is running
  • port: which TCP port to connect to

If Rails says it cannot connect to localhost:5432, the first question is not whether the gem is installed. The first question is: Is PostgreSQL actually running and listening on port 5432?

This matters in real programming because app startup often depends on external services such as:

  • databases
  • caches
  • message brokers
  • APIs

A large part of debugging is learning to separate:

  • application code problems
  • configuration problems
  • service availability problems

Mental Model

Think of Rails as a customer trying to enter a building.

  • host is the street address.
  • port is the door number.
  • PostgreSQL is the business inside.

If you get connection refused, Rails reached the address and tried the door, but nobody was there to answer.

That usually means one of these:

  • the building is closed → PostgreSQL is not running
  • the business moved to another door → PostgreSQL uses a different port
  • you went to the wrong address → wrong host in database.yml

So the fix is usually not rewriting Rails code. It is checking the address, the door, and whether the business is open.

Take Quiz

Syntax and Examples

In Rails, a PostgreSQL database connection is commonly configured like this:

development:
  adapter: postgresql
  encoding: unicode
  database: my_app_development
  username: myuser
  password: secret
  host: localhost
  port: 5432

A more minimal version often works too:

development:
  adapter: postgresql
  encoding: unicode
  database: my_app_development
  pool: 5

If PostgreSQL is installed locally and configured with default settings, Rails may connect without explicitly setting host, port, username, or password.

Example: checking whether PostgreSQL is reachable

From your terminal, try:

psql -h localhost -p 5432 -U postgres -d postgres

What this means:

  • -h localhost → connect to your local machine
  • -p 5432 → use PostgreSQL's default port
  • -U postgres → log in as user postgres
  • -d postgres → connect to the default postgres database

If this fails with connection refused, the problem is not Rails code. It means PostgreSQL is not reachable at that address.

Example: creating the Rails database

If PostgreSQL is running but your app database does not yet exist, run:

bundle exec rake db:create

For newer Rails versions, the equivalent is often:

bin/rails db:create

Example: using the correct local username

Sometimes your local PostgreSQL user matches your macOS username:

development:
  adapter: postgresql
  encoding: unicode
  database: metals_directory_development
  username: your_mac_username
  host: localhost
  port: 5432

Notice one important naming detail: database names commonly use underscores, such as metals_directory_development, not hyphens. Hyphens can cause confusion and often need quoting in SQL contexts.

Step by Step Execution

Consider this Rails configuration:

development:
  adapter: postgresql
  database: my_app_development
  host: localhost
  port: 5432

When you start Rails and load a page, this is roughly what happens:

  1. Rails boots the application.
  2. Active Record reads config/database.yml.
  3. It sees that the development environment uses PostgreSQL.
  4. It asks the pg gem to open a connection to:
    • host: localhost
    • port: 5432
    • database: my_app_development
  5. The operating system attempts a TCP connection to localhost:5432.
  6. If PostgreSQL is listening there, the connection continues.
  7. If nothing is listening there, the OS returns connection refused.
  8. The pg gem raises PG::ConnectionBad.
  9. Rails cannot continue because it needs the database connection.

Small troubleshooting trace

Command:

lsof -i :5432

Possible outcomes:

  • Shows a PostgreSQL process → PostgreSQL is likely running on port 5432.
  • Shows nothing → nothing is listening on that port, so Rails cannot connect there.

Another useful command:

pg_isready -h localhost -p 5432

Typical interpretation:

  • accepting connections → PostgreSQL is up
  • no response or similar → PostgreSQL is not reachable there

This step-by-step approach helps you confirm the exact layer where the failure happens.

Real World Use Cases

This kind of debugging appears constantly in real software work.

Local app development

A Rails app connects to PostgreSQL on your machine. If the database service is stopped after a reboot, the app fails at startup.

Team onboarding

A developer clones a project, installs dependencies, and runs the app. The code is fine, but PostgreSQL was never started or the local user/database was never created.

CI and test environments

Automated test jobs fail because the database service was not started before running migrations.

Docker or container setups

The app uses localhost, but PostgreSQL actually runs in another container and should be accessed by service name instead.

Production deployment

An app deploy succeeds, but runtime requests fail because the configured database host or port is incorrect.

In all these cases, the main skill is the same: confirm whether the service exists, is reachable, and matches the application configuration.

Take Quiz

Real Codebase Usage

In real projects, developers usually treat database connectivity as a configuration and environment problem first.

Common patterns

1. Environment-specific configuration

Different environments use different databases:

development:
  adapter: postgresql
  database: my_app_development

test:
  adapter: postgresql
  database: my_app_test

2. Environment variables

Instead of hardcoding credentials, teams often use environment variables:

development:
  adapter: postgresql
  database: my_app_development
  username: <%= ENV['PGUSER'] %>
  password: <%= ENV['PGPASSWORD'] %>
  host: <%= ENV.fetch('PGHOST', 'localhost') %>
  port: <%= ENV.fetch('PGPORT', 5432) %>

This makes config portable across machines.

3. Setup scripts

Projects often include setup steps such as:

bin/setup
bin/rails db:create db:migrate

This helps ensure the database exists before the app starts.

4. Guard-clause style troubleshooting

Developers often diagnose database problems in this order:

  • Is PostgreSQL installed?
  • Is PostgreSQL running?
  • Is it listening on the expected host/port?
  • Does the user exist?
  • Does the database exist?
  • Does database.yml match reality?

This is a guard-clause mindset for debugging: eliminate the simplest failure first.

5. Service-specific logging

Rather than only reading the Rails stack trace, developers also inspect PostgreSQL logs and service status. That is often where the real answer appears.

Common Mistakes

1. Reinstalling gems before checking whether PostgreSQL is running

A pg gem issue and a database service issue are different things.

If you see connection refused, check the service first:

pg_isready -h localhost -p 5432

2. Assuming localhost always works

Sometimes PostgreSQL is configured to use a Unix socket or a different host.

Broken assumption:

host: localhost
port: 5432

If PostgreSQL is not listening on TCP port 5432, this fails.

3. Forgetting to create the database

Even after PostgreSQL is running, your app database may not exist yet.

Run:

bundle exec rake db:create
bundle exec rake db:migrate

4. Using an invalid or awkward database name

Your config shows:

database: metals-directory_development

Hyphens in PostgreSQL identifiers can be problematic because they often require quoting. Prefer underscores:

database: metals_directory_development

5. Leaving username blank when your setup requires one

Blank username may work on some local setups, but not all.

Safer example:

username: your_local_username

6. Not checking whether the port is correct

PostgreSQL defaults to 5432, but your installation might use another port.

Check with a service or config command rather than guessing.

7. Confusing error types

These errors mean different things:

  • connection refused → service not reachable
  • password authentication failed → bad credentials
  • database does not exist → missing database

Fixing the wrong layer wastes time.

Comparisons

Error / SituationWhat it usually meansMost likely next step
connection refusedNo service is listening on that host/portStart PostgreSQL or fix host/port
password authentication failedPostgreSQL is running, but credentials are wrongFix username/password
database does not existPostgreSQL is running, but the named DB is missingCreate the database
could not translate host nameHostname is invalid or DNS failedFix host value
Configuration choiceMeaningWhen to use it
host: localhostConnect via TCP to local machineCommon when PostgreSQL listens on TCP
no host setMay use local default behavior, often socketsUseful for simple local setups
explicit port: 5432Use default PostgreSQL portGood when you know the service uses 5432
custom portConnect to a non-default PostgreSQL portNeeded if your installation changed the port
Naming styleExampleRecommendation
Hyphenated database namemetals-directory_developmentAvoid if possible
Underscored database namemetals_directory_developmentPreferred

The key comparison is this: Rails config problems and PostgreSQL service problems can look similar from the app side, but the fix depends on which layer is actually broken.

Take Quiz

Cheat Sheet

# Basic Rails PostgreSQL config
development:
  adapter: postgresql
  encoding: unicode
  database: my_app_development
  username: myuser
  password: secret
  host: localhost
  port: 5432
# Check whether PostgreSQL is accepting connections
pg_isready -h localhost -p 5432

# Try connecting manually
psql -h localhost -p 5432 -U postgres -d postgres

# See whether anything is listening on port 5432
lsof -i :5432

# Create app databases
bundle exec rake db:create
bundle exec rake db:migrate

What connection refused means

  • Rails reached the host
  • But no process accepted the connection on that port
  • Usually PostgreSQL is not running, not listening on that port, or database.yml is wrong

Good troubleshooting order

  1. Check that PostgreSQL is installed
  2. Check that PostgreSQL is running
  3. Check that it listens on localhost:5432
  4. Test with psql
  5. Verify database.yml
  6. Create the database
  7. Run migrations

Practical tips

  • Prefer underscores in database names
  • Do not assume blank username always works
  • connection refused is usually not a Rails code bug
  • Check service status before reinstalling gems

FAQ

What does PG::ConnectionBad mean in Rails?

It means the PostgreSQL driver could not establish a connection. The exact reason depends on the rest of the message.

What does connection refused mean for PostgreSQL?

It usually means nothing is listening on the host and port Rails tried to use, such as localhost:5432.

Can this happen even if the pg gem is installed correctly?

Yes. The gem can be installed properly while PostgreSQL itself is stopped or misconfigured.

Should I always set host: localhost in database.yml?

Not always. Some local setups work better without it, especially when using local socket-based connections.

Why is Rails checking the database when I only start the server?

Rails and Active Record often check the database during boot or on the first request because the app needs schema and migration information.

Could the database name be part of the problem?

Yes. If the database does not exist or uses an awkward name such as one with hyphens, it can cause issues. Underscores are safer.

How do I know whether the problem is PostgreSQL or Rails config?

Try connecting manually with psql. If manual connection fails, the issue is probably PostgreSQL service or system configuration rather than Rails code.

What should I check first on macOS?

First confirm PostgreSQL is running and listening on the expected port. The operating system version is usually not the core issue by itself.

Take Quiz

Mini Project

Description

Build a small Rails-style PostgreSQL connection checker script in Ruby. The project demonstrates how to verify database connectivity outside the full Rails boot process, which helps you separate app problems from service problems.

Goal

Create a Ruby script that attempts to connect to PostgreSQL using the same settings as a Rails app and prints a clear success or failure message.

Requirements

  • Read connection settings from variables in the script
  • Attempt a PostgreSQL connection using the pg gem
  • Print a success message if the connection works
  • Print the exact error message if the connection fails
Take Quiz

Keep learning

Related questions

View more