GitHub Actions: Canceling Since a Higher Priority Run of Concurrency Group
Fix GitHub Actions runs canceled mid-flight by a concurrency group: understand cancel-in-progress, deploy races, and how to queue instead of kill jobs.
- #automation
- #devops
- #troubleshooting
- #errors
Fixing errors like this? Get 500 free DevOps AI prompts
500 copy-paste AI prompts for the stack you actually run — one PDF, free.
Overview
GitHub Actions lets a workflow declare a concurrency group so only one run per group proceeds at a time. When a newer run starts and cancel-in-progress: true, GitHub cancels the running one. The canceled job’s log ends with:
Canceling since a higher priority waiting request for 'deploy-main' exists
Error: The operation was canceled.
This is not a crash — it is GitHub enforcing the concurrency policy. But when the canceled run was a deploy or a long migration, an unexpected cancellation mid-flight can leave a release half-applied.
Symptoms
- A workflow run flips to
CancelledwithCanceling since a higher priority waiting request for '<group>' exists. - Cancellations correlate with rapid pushes to the same branch or repeated
workflow_dispatchtriggers. - A deploy job is killed partway, leaving infrastructure or a release in a partial state.
- Two runs of the same pipeline never run together; the older one always dies.
- Steps after a
cancel-in-progressshowThe operation was canceled.
Common Root Causes
cancel-in-progress: trueon a deploy pipeline — intended for CI (cancel stale PR builds) but applied to deploys, so a new push kills an in-flight release.- Too-coarse concurrency key — a group like
deploy(no ref) makes unrelated branches cancel each other. - Rapid successive triggers — several pushes or dispatches in seconds, each superseding the last.
- Shared group across environments — staging and production sharing one concurrency group so a staging run cancels a production one.
- Matrix or reusable workflows — a parent and child sharing a group and canceling one another.
- Expecting queueing but getting cancellation — assuming runs queue when
cancel-in-progressis set to cancel.
Diagnostic Workflow
Find the concurrency configuration in the workflow file:
grep -RnA3 'concurrency:' .github/workflows/
Inspect recent runs and why they were canceled:
gh run list --workflow deploy.yml --limit 20
gh run view <run-id> --log | grep -i 'canceling since\|higher priority\|was canceled'
Check what triggered the superseding run (pushes close in time):
gh api repos/:owner/:repo/actions/workflows/deploy.yml/runs \
--jq '.workflow_runs[] | {id, event, head_branch, status, conclusion, created_at}'
Confirm whether the group key includes the ref (coarse keys cause cross-branch cancels):
# concurrency:
# group: deploy-${{ github.ref }} <- per-branch, correct
# cancel-in-progress: true <- kills in-flight; wrong for deploys
Example Root Cause Analysis
A team reported production deploys “randomly dying.” Their deploy.yml had:
concurrency:
group: deploy
cancel-in-progress: true
gh run list showed two deploys created 18 seconds apart after a fast follow-up commit. The first run — mid-way through a terraform apply — logged Canceling since a higher priority waiting request for 'deploy' exists and stopped, leaving Terraform state locked and the change half-applied.
Two problems compounded: the group deploy had no ref, and cancel-in-progress: true meant the newer push killed the running apply instead of waiting for it. The fix was to make the group per-ref and, critically, to NOT cancel in-progress deploys — let them queue:
concurrency:
group: deploy-${{ github.ref }}
cancel-in-progress: false
With cancel-in-progress: false, the second push waits until the first apply finishes, so a deploy is never interrupted. cancel-in-progress: true was kept only on the PR CI workflow, where killing a stale build is exactly what you want.
Prevention Best Practices
- Use
cancel-in-progress: truefor CI/PR builds where stale runs are wasteful, andcancel-in-progress: falsefor deploys and migrations that must not be interrupted. - Scope the concurrency
groupwith${{ github.ref }}(or environment) so unrelated branches and environments do not cancel each other. - Never share one concurrency group across staging and production.
- Make deploy steps idempotent and recoverable so a rare interruption does not leave a locked or half-applied state.
- Debounce triggers (path filters,
workflow_dispatchdiscipline) to reduce superseding runs. - Document the concurrency intent in a comment so the next editor does not toggle cancellation blindly.
Quick Command Reference
# Find concurrency config
grep -RnA3 'concurrency:' .github/workflows/
# List recent runs and conclusions
gh run list --workflow deploy.yml --limit 20
# Confirm the cancellation reason
gh run view <run-id> --log | grep -i 'canceling since\|higher priority'
# Inspect triggering events/timing via API
gh api repos/:owner/:repo/actions/workflows/deploy.yml/runs \
--jq '.workflow_runs[] | {event, head_branch, conclusion, created_at}'
Conclusion
“Canceling since a higher priority waiting request” is GitHub Actions doing exactly what the concurrency block told it to. The danger is applying CI’s cancel-stale-builds instinct to deploys, where killing an in-flight run leaves releases half-applied. Scope the group per ref and set cancel-in-progress: false on anything that mutates real state, so concurrent triggers queue instead of interrupt — and reserve cancellation for the disposable PR builds where it belongs.
Fixed it? Get 500 Automation & DevOps AI prompts — free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.
Did this fix your issue?
Get 500 Battle-Tested DevOps AI Prompts — Free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.