Skip to content
Latchkey

Liquibase "liquibase.exception.LockException" in CI

Liquibase threw a LockException after failing to acquire the changelog lock. The lock is held - typically because a previous run died without releasing it, or another migration is running concurrently.

What this error means

The Liquibase step fails with LockException: Could not acquire change log lock, naming who holds it and since when. Unlike the silent "waiting" hang, this raises and fails the job.

liquibase output
Unexpected error running Liquibase: Could not acquire change log lock.
Currently locked by runner-3 (10.0.0.3) since 2026-06-25 08:02
liquibase.exception.LockException: Could not acquire change log lock.

Common causes

Stale lock left by a killed run

A cancelled, timed-out, or OOM-killed run never released the lock, so the DATABASECHANGELOGLOCK row stays locked and the next attempt cannot acquire it.

Concurrent migration in progress

Another pipeline or process is actively migrating the same database and currently holds the lock.

How to fix it

Confirm no live run, then release the lock

Check the lock owner/timestamp; if it is from a dead job, release it and retry.

Terminal
liquibase releaseLocks   # only when no other migration is active
liquibase update

Prevent overlap with concurrency control

  1. Put migration jobs in a CI concurrency group so only one runs at a time.
  2. Make jobs idempotent and able to release the lock on cancellation.
  3. Set a step timeout so a stuck acquisition fails fast and surfaces the stale lock.

How to prevent it

  • Serialize migrations with a concurrency group.
  • Clear stale locks at the start of a controlled, single-writer deploy.
  • Use timeouts so a stuck lock acquisition fails fast instead of hanging.

Frequently asked questions

What causes ""liquibase.exception.LockException""?
A cancelled, timed-out, or OOM-killed run never released the lock, so the DATABASECHANGELOGLOCK row stays locked and the next attempt cannot acquire it.
How do I fix "liquibase.exception.LockException"?
Check the lock owner/timestamp; if it is from a dead job, release it and retry.
Can Latchkey fix this automatically?
Yes. Latchkey runs your GitHub Actions on managed runners that detect this failure, apply the fix, and retry the job automatically - self-healing is on by default.

Related guides

References

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