Flyway/Liquibase Migration Failed in Tests in CI - Fix the Migration
A test that boots the schema via Flyway or Liquibase fails when a migration cannot apply - a syntax error, a checksum that no longer matches an already-applied script, or SQL that works on prod's database but not the test database (e.g. H2 vs PostgreSQL).
What this error means
Test setup fails with FlywayException: Migration V5__add_index.sql failed or liquibase ... Validation Failed: change sets check sum. The context (or DB bootstrap) aborts before tests run.
org.flywaydb.core.api.FlywayException: Validate failed: Migrations have failed validation
Migration checksum mismatch for migration version 5
-> Applied to database : 1456789012
-> Resolved locally : 998877665Common causes
Edited an already-applied migration (checksum mismatch)
Changing a migration that was already applied changes its checksum, so validation fails. Migrations are immutable once applied.
Dialect difference between test and prod DB
SQL that runs on PostgreSQL may fail on an in-memory H2 (or vice versa), so the migration fails only in the test environment.
How to fix it
Add a new migration instead of editing an old one
Never modify applied migrations; ship a corrective forward migration.
-- Wrong: editing V5__add_index.sql (changes its checksum)
-- Right: add a new versioned migration
-- db/migration/V6__fix_index.sql
DROP INDEX IF EXISTS idx_orders_user;
CREATE INDEX idx_orders_user ON orders (user_id);Test against the same database as prod
- Run migrations in tests against the real engine via Testcontainers (PostgreSQL/MySQL), not H2, to catch dialect issues.
- If you must use H2, set PostgreSQL compatibility mode and keep SQL portable.
- Resolve a checksum mismatch by reverting the edit and adding a new migration (or
flyway repaironly in disposable test DBs).
How to prevent it
- Treat applied migrations as immutable, run migration tests against the production database engine via Testcontainers, and keep SQL portable or engine-specific deliberately.