GitHub Actions Label-Based Routing Sends Jobs to the Wrong Runner
A job lands on the wrong runner pool because multiple fleets share a label. With overlapping labels, GitHub may dispatch to any matching runner, so a job meant for GPU or arm64 runs somewhere else.
What this error means
A job runs on an unexpected runner - wrong architecture, missing tools, or a pool you meant to reserve - because more than one runner set matched the requested labels.
# both an x64 and an arm64 fleet are labeled [self-hosted, build]
runs-on: [self-hosted, build] # may match either fleetCommon causes
Labels overlap across fleets
When two runner groups share the same labels, any of them can claim a matching job, so routing is not deterministic.
Too-generic label set
Requesting only broad labels (self-hosted, linux) without a distinguishing one lets unintended runners pick up the job.
How to fix it
Add a distinguishing label
Give each fleet a unique label and request it so only the intended pool matches.
# arm64 fleet carries 'arm64'; x64 fleet carries 'x64'
runs-on: [self-hosted, build, arm64]Use runner groups for isolation
- Assign unique, specific labels per fleet and request the exact set.
- Use runner groups to restrict which repos and jobs reach a fleet.
- Avoid relying on broad shared labels for routing-sensitive jobs.
How to prevent it
- Give every runner fleet a unique distinguishing label.
- Request specific labels for routing-sensitive jobs.
- Isolate sensitive fleets behind runner groups.