GitHub Actions Job Stuck "Waiting for a runner to pick up this job"
A job is queued but no runner ever picks it up. Either no online runner matches every requested label, your self-hosted runner is offline, or you have hit a concurrency or billing limit.
What this error means
The job sits indefinitely with "Waiting for a runner to pick up this job" and never starts. There is no failure, just an unbounded queue wait.
Requested labels: self-hosted, gpu, linux
Waiting for a runner to pick up this job...Common causes
No runner matches all requested labels
runs-on requires a runner that carries every label listed. If no online runner has all of them (for example a missing gpu label), the job waits forever.
Self-hosted runner offline or busy
A self-hosted runner that crashed, lost network, or is already running its max jobs cannot accept the queued job.
Out of concurrency or minutes
Hitting the plan concurrency cap, or running out of included minutes/billing, leaves hosted jobs queued until capacity frees up.
How to fix it
Match runs-on to an available runner
Use a label set that an online runner actually carries, or a valid GitHub-hosted label.
# GitHub-hosted
runs-on: ubuntu-latest
# self-hosted: every label must exist on an online runner
runs-on: [self-hosted, linux, x64]Bring runners online and check limits
- Confirm self-hosted runners show as Idle/Online in repo or org settings.
- Check that billing is active and you have not exhausted included minutes.
- Verify you are within the concurrent-jobs limit for your plan.
How to prevent it
- Keep runs-on labels in sync with the labels your runners actually register.
- Monitor self-hosted runner health and auto-restart offline runners.
- Watch concurrency and minutes usage so jobs do not silently queue.