Introduction
When a GitHub Actions workflow stays queued with a self-hosted runner setup, the problem is usually not the workflow logic itself. GitHub cannot find an online runner that both belongs to the correct scope and matches the requested labels. That can mean the runner process is offline, the label set is wrong, or the runner is busy and there is no spare capacity.
Symptoms
- Jobs remain queued with no log output
- GitHub reports it is waiting for a runner to come online
- The runner host exists, but workflows never get assigned
- The problem appears after a reboot, label change, or runner group update
Common Causes
- The self-hosted runner service is stopped or unhealthy
- The workflow requests labels that no registered runner matches
- The repository or organization runner group does not allow this workflow to use the runner
- All matching runners are busy and there is no concurrency headroom
Step-by-Step Fix
- 1.Check the runner status in GitHub and on the host
- 2.Confirm the runner is truly online instead of assuming the host being up means the runner listener is healthy.
sudo systemctl status actions.runner- 1.Verify the workflow label set matches the registered runner
- 2.A runner must satisfy every label in
runs-on, not just one of them.
runs-on: [self-hosted, linux, x64]- 1.Review runner group and repository access
- 2.A runner can be online and still unusable if the repository is not permitted to consume that runner group.
- 3.Add capacity or another runner if the queue problem is load-related
- 4.If the runner is online but constantly busy, the fix is scaling, not debugging.
Prevention
- Run self-hosted runners as managed services with automatic restart
- Keep runner labels standardized and documented
- Monitor queue depth and runner offline state together
- Maintain at least one spare runner for critical workflows during peak periods