Skip to content
🎉 Launch sale:50% off everything over $22 — automatically applied at checkout· ends Aug 2Shop the sale →
DevOps AI ToolKit
Newsletter
All guides
AI for Automation By James Joyner IV · · 8 min read Last reviewed Jul 2026

GitHub Actions: Canceling Since a Higher Priority Run of Concurrency Group

Quick answer

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
Free toolkit

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 Cancelled with Canceling since a higher priority waiting request for '<group>' exists.
  • Cancellations correlate with rapid pushes to the same branch or repeated workflow_dispatch triggers.
  • 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-progress show The operation was canceled.

Common Root Causes

  • cancel-in-progress: true on 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-progress is 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: true for CI/PR builds where stale runs are wasteful, and cancel-in-progress: false for deploys and migrations that must not be interrupted.
  • Scope the concurrency group with ${{ 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_dispatch discipline) 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.

Free download · 368-page PDF

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?

Free download · 368-page PDF

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.