{"record":{"id":"52591cfc9c201fef","repo":"quarkusio/quarkus","slug":"error-starting-liquibase","errorCode":null,"errorMessage":"Error starting Liquibase","messagePattern":"Error starting Liquibase","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"critical","filePath":"extensions/liquibase/liquibase/runtime/src/main/java/io/quarkus/liquibase/runtime/LiquibaseRecorder.java","lineNumber":108,"sourceCode":"            }\n            if (dataSourceConfig.migrateAtStart()) {\n                var lockService = LockServiceFactory.getInstance()\n                        .getLockService(liquibase.getDatabase());\n                lockService.waitForLock();\n                try {\n                    if (dataSourceConfig.validateOnMigrate()) {\n                        liquibase.validate();\n                    }\n                    liquibase.update(liquibaseFactory.createContexts(), liquibaseFactory.createLabels());\n                } finally {\n                    lockService.releaseLock();\n                }\n            }\n        } catch (InactiveBeanException e) {\n            // These exceptions should be self-explanatory\n            throw e;\n        } catch (Exception e) {\n            throw new IllegalStateException(\"Error starting Liquibase\", e);\n        }\n    }\n\n}\n","sourceCodeStart":90,"sourceCodeEnd":113,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/liquibase/liquibase/runtime/src/main/java/io/quarkus/liquibase/runtime/LiquibaseRecorder.java#L90-L113","documentation":"LiquibaseRecorder.doStartActions wraps startup migration (clean-at-start dropAll and migrate-at-start update) in a catch-all that rethrows as IllegalStateException('Error starting Liquibase'). Only self-explanatory InactiveBeanExceptions pass through untouched. This means Liquibase migration failed during application startup, and the real reason (changelog parse error, validation failure, DB lock, connection failure) is the wrapped cause.","triggerScenarios":"quarkus.liquibase.migrate-at-start or clean-at-start is true and liquibase.update()/dropAll()/validate() throws — changelog file missing or invalid XML/YAML, checksum validation mismatch, database changelog lock held, Liquibase-to-DB version incompatibility, or datasource connection failure.","commonSituations":"Changelog edited after being applied (checksum mismatch); two app instances contending on DATABASECHANGELOGLOCK; wrong changelog path in quarkus.liquibase.change-log; newer Liquibase bundled with Quarkus vs older DB; migration SQL error from schema drift.","solutions":["Read the 'Caused by' chain — LiquibaseException/ValidationFailure names the failing changeset.","Clear a stale changelog lock: DELETE FROM DATABASECHANGELOGLOCK; or use liquibase --force-release-locks.","Fix or roll back the edited changeset causing validation/checksum failure (run clearCheckSums only knowingly).","Verify quarkus.liquibase.change-log points to an existing resource and the datasource is reachable.","Pin or align the Liquibase version with your database engine's supported matrix."],"exampleFix":"// before: edits an applied changeset -> checksum mismatch\n<changeSet id=\"1\" author=\"me\">\n  <sql>ALTER TABLE t ADD COLUMN b int</sql>\n</changeSet>\n// after: add a new changeset instead\n<changeSet id=\"1\" author=\"me\">\n  <sql>ALTER TABLE t ADD COLUMN a int</sql>\n</changeSet>\n<changeSet id=\"2\" author=\"me\">\n  <sql>ALTER TABLE t ADD COLUMN b int</sql>\n</changeSet>","handlingStrategy":"try-catch","validationCode":"// Pre-startup checks before migrate-at-start runs:\nassert Files.exists(Path.of(\"src/main/resources/db/change-log.xml\")) : \"changelog missing\";\n// and check for a stale lock:\n// SELECT COUNT(*) FROM DATABASECHANGELOGLOCK WHERE LOCKED = TRUE;","typeGuard":null,"tryCatchPattern":"try {\n    app.start(); // or run migrations via LiquibaseFactory directly\n} catch (IllegalStateException e) {\n    if (\"Error starting Liquibase\".equals(e.getMessage())) {\n        Throwable cause = e.getCause();\n        if (cause instanceof liquibase.exception.LockException) {\n            log.error(\"Changelog lock held — clear DATABASECHANGELOGLOCK\");\n        } else if (cause instanceof liquibase.exception.ValidationFailedException) {\n            log.error(\"Changeset validation failed: {}\", cause.getMessage());\n        }\n    }\n}","preventionTips":["Never edit already-applied changesets — always append new ones.","Enable quarkus.liquibase.validate-on-migrate and keep it on.","Add a startup readiness step that checks DATABASECHANGELOGLOCK.","Keep one writer per schema at deploy time (avoid overlapping replicas migrating).","Pin the Liquibase/DB version combination in a staging test before upgrades."],"tags":["liquibase","database-migration","startup","changelog"],"backgroundTag":"liquibase-migration-failed","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}