Skip to content
Latchkey

MySQL "Connection refused" before "ready for connections" in CI

The MySQL container is starting but the server has not yet printed "ready for connections" and is not listening on 3306. Early connects are refused. A mysqladmin ping healthcheck gates steps until it is ready.

What this error means

The first connection fails with "Can't connect to MySQL server on '127.0.0.1' (111)" or a refused TCP connect, and the container log later shows "[Server] ... ready for connections".

Terminal
ERROR 2003 (HY000): Can't connect to MySQL server on '127.0.0.1:3306' (111)

Common causes

MySQL is still initializing the data directory

On first boot the image runs initialization (creating the system tables and any MYSQL_DATABASE). The port is not accepting connections until that finishes.

No healthcheck waits for "ready for connections"

Without a mysqladmin ping health command, steps run as soon as the container exists, before the server is up.

How to fix it

Gate steps with a mysqladmin ping healthcheck

GitHub Actions holds job steps until the service is healthy.

.github/workflows/ci.yml
services:
  mysql:
    image: mysql:8.0
    env:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: app_test
    ports: ['3306:3306']
    options: >-
      --health-cmd "mysqladmin ping -h 127.0.0.1 -uroot -proot --silent"
      --health-interval 5s
      --health-timeout 5s
      --health-retries 15

Poll with mysqladmin ping in a loop

For docker-compose, wait until ping succeeds before running migrations.

Terminal
until mysqladmin ping -h 127.0.0.1 -uroot -proot --silent; do
  echo "waiting for mysql"; sleep 2
done

How to prevent it

  • Always add a mysqladmin ping healthcheck to the MySQL service.
  • Allow generous --health-retries; MySQL first boot can take 10-20s.
  • Connect over TCP to 127.0.0.1:3306, not a socket, from steps.

Frequently asked questions

What causes "MySQL "Connection refused" (not ready)"?
On first boot the image runs initialization (creating the system tables and any MYSQL_DATABASE). The port is not accepting connections until that finishes.
How do I fix MySQL "Connection refused" (not ready)?
GitHub Actions holds job steps until the service is healthy.

Related guides

References

Latchkey auto-heals failures like this one - detected, fixed, and retried without you. Start free → 30-day trial · No credit card