Pulumi "the stack is currently locked" - Fix in CI
Pulumi takes an exclusive lock on a stack for the duration of an update. The lock is still held - either a real update is running concurrently, or a previous job was killed before it could release it.
What this error means
pulumi up (or preview/destroy) refuses to start, reporting the stack is locked and pointing at a lock file in the backend with the host and time that acquired it. If no update is actually running, the lock is stale from a cancelled or OOM-killed job.
error: the stack is currently locked by 1 lock(s). Either wait for the other
process(es) to end or delete the lock file with `pulumi cancel`.
s3://my-pulumi-state/.pulumi/locks/organization/proj/dev/<id>.json: created by
runner@fv-az123 (pid 4210) at 2026-06-25T10:14:02ZCommon causes
A concurrent update holds the lock
Two pipelines (or a manual run plus CI) target the same stack at once. Pulumi serializes updates with a lock, so the second one is blocked until the first finishes.
A stale lock from a killed job
If a previous pulumi up was cancelled, timed out, or the runner was OOM-killed, the lock file in the state backend is never cleaned up and lingers, blocking the next run.
How to fix it
Confirm nothing is actually running, then cancel
Only cancel once you are sure no real update is in flight - cancelling a live update can corrupt state. When the lock is stale from a dead job, pulumi cancel clears it.
pulumi stack select org/proj/dev
pulumi cancel --yes # releases the stale lock for this stackSerialize deployments to one stack
Prevent two jobs from racing the same stack by gating on a concurrency group so only one update runs at a time.
concurrency:
group: pulumi-${{ github.workflow }}-dev
cancel-in-progress: falseHow to prevent it
- Use a CI concurrency group keyed on the stack so updates never overlap.
- Give Pulumi steps a generous timeout so the runner is not killed mid-update, leaving a stale lock.
- Reserve
pulumi cancelfor confirmed-dead jobs, not as a routine pre-step.