Skip to content
Latchkey

Java Tests "Connection refused" to Test DB in CI - Fix Connectivity

A Connection refused to a test database means nothing was listening at that host:port when the test connected - the DB service had not finished starting, was on a different host/port, or was not started at all. Service-container startup races are a frequent transient cause.

What this error means

A test fails with java.net.ConnectException: Connection refused while opening a JDBC connection (e.g. to localhost:5432). Often the DB service container is still booting when the first test connects.

junit
Caused by: java.net.ConnectException: Connection refused
        at java.base/sun.nio.ch.Net.connect0(Native Method)
org.postgresql.util.PSQLException: Connection to localhost:5432 refused.
Check that the hostname and port are correct and the server is accepting TCP/IP connections.

Common causes

Database not ready when tests started

A services: DB container (or a separately launched DB) accepts connections only after it finishes initializing; tests that connect first get "Connection refused" (transient).

Wrong host/port or DB not started

The JDBC URL points at the wrong host/port, or the DB was never started in CI, so the refusal is deterministic until fixed.

How to fix it

Wait for the DB to be healthy before tests

Gate tests on a health check so they only run once the DB accepts connections.

.github/workflows/ci.yml
services:
  postgres:
    image: postgres:16
    env: { POSTGRES_PASSWORD: test }
    ports: ['5432:5432']
    options: >-
      --health-cmd "pg_isready -U postgres"
      --health-interval 5s --health-timeout 5s --health-retries 10

Verify the JDBC target

  1. Confirm the JDBC URL host/port match the service mapping (e.g. localhost:5432).
  2. For flaky readiness, prefer Testcontainers, which waits for the DB before returning the URL.
  3. Add a brief connection retry in test setup for service-container races.

How to prevent it

  • Gate tests on a DB health check (or use Testcontainers), and keep the JDBC URL in sync with the service mapping so connectivity is deterministic.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →