GitHub Actions Job Picked by Wrong Self-Hosted Runner (Label Overlap)
A job runs on a self-hosted runner you did not intend because several runners share the requested labels. The "wrong" runner lacks a tool, uses a different architecture, or has stale state, so the job fails in confusing ways.
What this error means
A job sometimes succeeds and sometimes fails with missing tools or arch mismatches, and the difference correlates with which self-hosted runner happened to pick it up - the labels are not specific enough to target one runner reliably.
# both runners carry [self-hosted, linux]; only one has CUDA
runs-on: [self-hosted, linux]
# job lands on the non-GPU runner and fails: nvcc: command not foundCommon causes
Labels too broad to target one runner
Multiple runners share a generic label set, so GitHub can dispatch the job to any of them. The one that picks it up may not have the tools or architecture the job needs.
Inconsistent labels across a fleet
Runners provisioned at different times carry different custom labels, so a job that needs a specific capability is not reliably routed to a runner that has it.
How to fix it
Add a distinguishing label
Give the capable runners a unique label and request it so only they can claim the job.
# configure the GPU runner with a gpu label
./config.sh --url <URL> --token <TOKEN> --labels self-hosted,linux,gpu
# then target it precisely
runs-on: [self-hosted, linux, gpu]Standardize labels across the fleet
- Define a consistent label scheme (os, arch, capability) for all runners.
- Request the full capability label set in runs-on so only matching runners qualify.
- Use runner groups to isolate special-purpose runners from general ones.
How to prevent it
- Give special-capability runners unique labels and request them explicitly.
- Keep a consistent labeling scheme across the runner fleet.
- Use runner groups to isolate hardware-specific runners.