Flyway validation fails with a checksum mismatch when a migration file has been modified after it was successfully applied to the database. Flyway stores checksums of migration files and verifies them on startup to detect unauthorized changes. Fixing requires either reverting the migration file changes, using `flyway repair` to realign checksums, or manually updating the schema history table in development environments.
Flyway is a database migration tool that maintains immutability of applied migrations. When a migration runs successfully, its checksum is stored in the `flyway_schema_history` table in PostgreSQL. On subsequent application startups, Flyway validates that each applied migration's checksum matches the stored value to detect accidental or unintended modifications. The "Migration checksum mismatch" error occurs when the calculated checksum of a migration file does not match the checksum recorded in `flyway_schema_history`. This indicates the migration file has been changed after it was applied to the database. Since migrations represent immutable contracts about the database state, Flyway treats this as a validation failure and prevents further execution until resolved. Common scenarios include: accidentally modifying an applied migration file (adding/removing SQL statements, changing indentation, or adding/removing comments), upgrading Flyway to a version with a different checksum algorithm, or having the same migration file with different paths across environments.
The error message displays the version and both checksums. Find the specific migration file and note the version number.
Flyway: Validate failed: Migration checksum mismatch for migration version 1.1
-> Applied to database: 1234567890
-> Resolved locally: -987654321
Either revert the changes to the migration, or run repair to update the schema history.The version number (e.g., "1.1") tells you which migration file is mismatched. Check your migrations directory (typically db/migration/) for V1.1__*.sql or similar.
Check if the migration file matches what was originally deployed. Compare the current version with version control history or backups.
# If using Git, check the file history
git log --oneline -- db/migration/V1.1__your_migration.sql
# View the diff between current and last committed version
git diff HEAD -- db/migration/V1.1__your_migration.sql
# Show the file as it was when deployed
git show HEAD:db/migration/V1.1__your_migration.sqlIf the file has been modified (intentionally or unintentionally), you have two paths forward:
1. Development: Revert to the original version or use flyway repair
2. Production: Revert changes and create a new migration file
If the modifications were accidental or unnecessary, restore the migration file to its original version:
# Restore from Git
git checkout HEAD -- db/migration/V1.1__your_migration.sql
# Or restore from backup
cp backup/V1.1__your_migration.sql db/migration/V1.1__your_migration.sqlAfter reverting, the checksum should match again and Flyway will validate successfully. This is the recommended approach for development environments or when changes should not have been made.
In development environments, you can use Flyway's repair command to realign checksums. This updates the flyway_schema_history table to match the current migration files, allowing validation to pass.
# Using Flyway CLI
flyway repair
# Using Maven
mvn flyway:repair
# Using Gradle
gradle flywayRepairThe repair command:
- Updates checksums of already-applied migrations to match current files
- Removes failed migrations from the history table
- Does NOT re-run migrations or modify the database schema
WARNING: Only use repair in development environments! In production, it can cause serious issues by hiding genuine problems with migrations. Instead, always create new migration files to fix issues.
If Flyway repair is not available or you need fine-grained control, manually update the flyway_schema_history table in PostgreSQL:
-- View the current schema history
SELECT version, checksum, success FROM flyway_schema_history ORDER BY version;
-- Update the checksum for the mismatched migration
UPDATE flyway_schema_history
SET checksum = -987654321 -- Use the "Resolved locally" checksum from error
WHERE version = '1.1';
-- Verify the update
SELECT version, checksum, success FROM flyway_schema_history WHERE version = '1.1';After updating, Flyway should validate successfully. However, manually modifying the schema history table is error-prone and should only be done as a last resort in development environments.
For production databases, never use repair or manual updates. Instead, create a new migration file to correct the database state:
-- db/migration/V1.2__fix_previous_migration.sql
-- Revert the incorrect changes from V1.1
DROP TABLE IF EXISTS incorrect_table;
DROP INDEX IF EXISTS incorrect_index;
-- Apply the correct changes
CREATE TABLE correct_table (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL
);Then delete or isolate the problematic V1.1 migration file so it will not be modified again. Create new migrations (V1.2, V1.3, etc.) for future changes. This ensures audit trails and allows rollback to previous versions if needed.
Follow these practices to avoid checksum mismatches:
1. Treat migrations as immutable: Once a migration is applied to any database, never modify it. Create new migrations instead.
# DON'T modify existing V1.1__migration.sql
# Instead, create a new one:
# V1.2__fix_v1.1_issue.sql2. Use version control: Keep migration files in Git with consistent formatting:
# Ensure consistent line endings (LF, not CRLF)
git config core.safecrlf true
echo "* text eol=lf" >> .gitattributes3. Document migration changes: Use Git commits to document why migrations were created:
git commit -m "V1.1__create_users_table.sql: Add user management schema"4. Run Flyway validate in CI/CD: Catch checksum mismatches before deployment:
# GitHub Actions example
- name: Validate migrations
run: mvn flyway:validate5. Use consistent Flyway configuration: Ensure all environments use the same Flyway version and configuration to avoid path-based checksum differences.
Checksum algorithm differences between Flyway versions can cause mismatches even when migration files are unchanged. Flyway 5.x to 6.x introduced a change where the checksum calculation may include the relative path of the migration file. If upgrading Flyway, run flyway repair once in development to update all checksums to the new algorithm, then commit the schema history state to version control.
For teams using multiple Flyway configurations or locations, ensure migration paths are consistent across all environments. Relative path differences (db/migrations/ vs migrations/ vs /migrations/) can cause different checksums for identical files.
If working with repeatable migrations (R prefix, e.g., R__populate_cache.sql), note that these are re-run if their checksum changes, unlike versioned migrations which are run once. Intentional changes to repeatable migrations are expected and do not cause validation errors.
PostgreSQL-specific behavior: Since PostgreSQL supports DDL transactions, a failed migration will automatically rollback all schema changes made during that migration. If you have a V1.1 migration that failed partway through, the database schema may be clean but the flyway_schema_history table will record it as failed. Use repair to remove the failed entry and re-run the corrected migration.
When using containerized Flyway (Docker), ensure migration files are properly mounted and have consistent paths. Using volumes with different mount points across containers can cause path-based checksum differences.
insufficient columns in unique constraint for partition key
How to fix "insufficient columns in unique constraint for partition key" in PostgreSQL
ERROR 42501: must be owner of table
How to fix "must be owner of table" in PostgreSQL
trigger cannot change partition destination
How to fix "Trigger cannot change partition destination" in PostgreSQL
SSL error: certificate does not match host name
SSL error: certificate does not match host name in PostgreSQL
No SSL connection
No SSL connection to PostgreSQL