Skip to content
Latchkey

Rails "Mysql2::Error" During Migrations in CI

The mysql2 adapter raised an error during migration. It covers two very different situations: failing to connect to MySQL at all, or MySQL rejecting a migration’s SQL. The message text tells you which.

What this error means

rails db:migrate fails with Mysql2::Error. A "Can't connect"/"Access denied" variant is a connection/auth problem; a "Duplicate column"/"Table exists" variant is a DDL/state problem. The two need different fixes.

Rails output
Mysql2::Error::ConnectionError: Can't connect to MySQL server on 'db' (111)
# or
Mysql2::Error: Duplicate column name 'status'

Common causes

Cannot connect or access denied

MySQL is not ready, the host/port is wrong, or the credentials/grants are incorrect. The migration never runs because the connection or auth fails first.

DDL conflicts with current schema

A "Duplicate column", "Table already exists", or constraint error means the migration SQL clashes with the database’s actual state - often a re-run against a non-clean database.

How to fix it

For connection/auth errors, fix readiness and credentials

Wait for MySQL and confirm the host, port, user, and password match the service.

Terminal
until mysqladmin ping -h "$DB_HOST" --silent; do sleep 1; done
bin/rails db:prepare

For DDL errors, reconcile schema state

  1. Read whether the object already exists or is missing.
  2. Run migrations against a clean CI database so each DDL statement runs once.
  3. Fix the migration if it genuinely conflicts with a prior one.

Set credentials from secrets

.github/workflows/ci.yml
env:
  DATABASE_URL: mysql2://root:${{ secrets.MYSQL_PASSWORD }}@db:3306/app_test

How to prevent it

  • Gate db:migrate on a MySQL readiness check.
  • Run migrations against a fresh CI database so DDL is applied once.
  • Keep credentials in secrets and aligned with the service grants.

Related guides

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