Using Runner Groups with GitHub Actions
A runner group decides which repositories and workflows may use a set of runners. Jobs that never start are usually blocked by group access, rarely by capacity.
Last verified:
A GitHub Actions runner group is the access boundary around a set of self-hosted runners: it decides which repositories may use those runners and, optionally, which workflow files, branches, tags, and commit SHAs may claim them. When a job sits at "Waiting for a runner" with an empty log and never starts, a runner group restriction is the usual cause, and the fix is a setting in GitHub organization settings rather than more runner capacity.
This guide separates a group block from a capacity wait, gives the troubleshooting checklist in the order the causes actually occur, shows where WarpBuild runners register and how workflow restrictions interact with a real workflow file, and puts a number on what a misconfigured group costs while it goes unnoticed.
Diagnosis
Two failures that look the same on the Actions tab
A job that starts late was queued and then claimed. Its log fills in, the run completes, and the wait shows up as the gap between created_at and started_at on the job object in the GitHub API. That is a capacity problem, and it responds to adding runners.
A job that never starts stays queued with an empty log view. No runner ever accepts it, so there is nothing to write to the log. Cancel it an hour later and the log is still empty. That shape points at a runner group or at a label.
Duration is the tell. Capacity waits drain as other jobs finish, so they resolve in minutes. A group block persists, because the passage of time changes nothing about whether the repository appears on the group's allowed list. If a job is still queued after every other job in the organization has finished, capacity is the wrong place to look.
WarpBuild provisions a fresh virtual machine for each job at the moment the job queues, so there is no pool to exhaust. Run as many jobs as your workflows need. Generally available Linux and Windows runners do not have plan-level concurrency caps. A queued WarpBuild job that never starts is therefore an access problem in almost every case, and the checklist below finds it.
The checklist, most likely cause first
Work these top to bottom. They are ordered so the causes that turn out to be the real one most often come first, and each check takes under a minute.
- The GitHub connection does not include the repository. The WarpBuild bot serves the repositories granted to the connection. A repository added after onboarding is the single most common miss.
- The repository is public and public repositories are disallowed on the group. GitHub disables self-hosted runners in public repositories by default, so this blocks an entire class of repositories at once and looks like a total outage in open-source repositories.
- The group's repository access list excludes the repository. This applies when the organization points WarpBuild at a group other than the default one.
- A workflow restriction on the group excludes this workflow. The subtlest cause, because most workflows in the repository keep working while one file, branch, or tag stays blocked.
- The
runs-onlabel matches no registered runner. A typo produces the identical symptom with no group involvement at all, so rule it out before opening a support thread.
The first four are group problems. The fifth is not, and it is worth checking last only because the first four are faster to verify from a single browser tab.
Fix
1. Confirm the repository is connected
Open https://app.warpbuild.com/settings/account, click Configure Runners on the GitHub connection, and read the repository list. Add the repository if it is missing. The connection must list a repository before runners can serve it.
2. Allow public repositories
WarpBuild registers itself as a self-hosted runner in the Default runner group (id 1) for your GitHub organization. GitHub disables the use of self-hosted runners, including managed ones, in public repositories by default. Until that setting changes, every job in every public repository in the organization queues and never starts.
Go to https://github.com/organizations/[YOUR_ORG]/settings/actions/runner-groups/1 and check the Allow public repositories box.
GitHub recommends keeping self-hosted runners off public repositories because a pull request from an outside contributor can run arbitrary code on shared infrastructure. WarpBuild runs each workflow inside an isolated virtual machine that is destroyed when the job ends, which is why enabling the setting is safe here. The public repositories documentation has the screenshot and the GitHub Enterprise note. If the billing question comes up in the same conversation, are GitHub Actions free for open source covers the free-minutes rules for public repositories.
3. Check repository access on the group
This step applies when your organization points WarpBuild at a group other than the default. Confirm which group that is at https://app.warpbuild.com/ci under Runners, then open GitHub Organization Settings, Actions, Runner groups, and select the same group. Check the repository access list there. A group set to selected repositories blocks every repository that was never added to it.
4. Check workflow restrictions
GitHub can pin a runner group to specific workflows. Each restriction is written as a full workflow path with a ref:
monalisa/octocat/.github/workflows/cd.yaml@refs/heads/mainThat entry allows cd.yaml on main and nothing else. GitHub supports restricting by workflow path, branch, sha, and tag, and each entry is an allow-list rule, so adding the first entry excludes every workflow you did not list. A pull request check defined in ci.yaml queues silently, and so does the same cd.yaml when it runs on a release tag instead of main.
The common issues guide documents both the group access check and the workflow restriction check with screenshots of the GitHub settings pages.
5. Rule out the label
Copy the label from the runner catalog rather than typing it. WarpBuild labels encode operating system, architecture, and size in one string, so a single wrong character produces a label that no runner advertises. How do I change the runner in a GitHub Actions workflow covers the runs-on edit itself, and runner group holds the plain definition if someone on the thread needs it.
If all five checks pass and jobs still queue, mail [email protected].
Configuration
Where runners register
WarpBuild runners join the Default runner group (id 1) unless the organization selects a different group in the WarpBuild dashboard under Runners. GitHub Enterprise supports creating multiple runner groups, so enterprise organizations are the ones most likely to run a non-default group and hit check 3 above.
BYOC runs on AWS, GCP, and Azure, and BYOC runners register into the group the same way, so every check on this page applies to runners in your own cloud account too.
A workflow that exercises the restriction
The workflow below lives at .github/workflows/ci.yaml and uses three of them:
name: ci
on:
pull_request:
push:
branches: [main]
jobs:
test:
runs-on: warp-ubuntu-latest-x64-8x
steps:
- uses: actions/checkout@v4
- name: Print runner identity
run: echo "name=$RUNNER_NAME os=$RUNNER_OS arch=$RUNNER_ARCH"
- uses: actions/setup-node@v4
with:
node-version: 22
- run: npm ci
- run: npm test
package:
runs-on: warp-ubuntu-latest-arm64-8x
steps:
- uses: actions/checkout@v4
- run: ./scripts/package.sh
deploy:
needs: [test, package]
if: github.ref == 'refs/heads/main'
runs-on: warp-ubuntu-latest-x64-4x
steps:
- uses: actions/checkout@v4
- run: ./scripts/deploy.shNow apply the restriction from step 4 to the group these runners belong to. The entry names cd.yaml, and this file is ci.yaml, so all three jobs queue and none of them start. The Print runner identity step is the cheap probe: when it never appears in the log, the job was never claimed, and the cause is access rather than anything inside the workflow.
The three labels in that workflow, plus the macOS and Windows labels a release pipeline usually adds, with the shapes and per-minute rates published on the pricing page, checked on 2026-08-13:
| Runner label | OS | vCPU | RAM | Storage | Rate per minute |
|---|---|---|---|---|---|
| warp-ubuntu-latest-x64-4x | Ubuntu 24.04 | 4 | 16 GB | 150GB SSD | $0.008 |
| warp-ubuntu-latest-x64-8x | Ubuntu 24.04 | 8 | 32 GB | 150GB SSD | $0.016 |
| warp-ubuntu-latest-arm64-8x | Ubuntu 24.04 | 8 | 32 GB | 150GB SSD | $0.012 |
| warp-macos-latest-arm64-6x | macOS 15 | 6 | 22 GB | 120GB SSD | $0.08 |
| warp-windows-latest-x64-4x | Windows Server 2022 | 4 | 16 GB | 256GB SSD | $0.016 |
A group restriction applies to every label in the group at once. Splitting a workflow across Linux, macOS, and Windows labels does nothing to route around it, which is why a matrix that fails on all legs at once is a strong signal for the group rather than for any one image.
Once jobs start reliably, the remaining wait is ordinary queue time. GitHub Actions queue times and how to fix them covers measuring it per runner label.
Cost or Time Model
What a blocked group costs on day one
Blocked jobs bill nothing, which is exactly why they stay unnoticed. The cost lands on engineers instead. Substitute your own repository count and run volume.
Assumptions:
- An organization with 6 public repositories, each averaging 8 workflow runs per working day.
- The
Allow public repositoriesbox is unchecked, so every one of those runs queues without starting. - Each blocked run holds up one engineer for 20 minutes: the wait on a pull request check, then the time spent working out why nothing is happening.
- A loaded engineer cost of $100 per hour.
The arithmetic: 6 repositories multiplied by 8 runs is 48 blocked runs on day one. 48 runs multiplied by 20 minutes is 960 minutes, or 16 engineer hours. At $100 per hour that is $1,600 for a single day, and the fix is one checkbox.
A workflow restriction costs less per day and lasts longer. It blocks one workflow file while the rest of the repository behaves normally, so the failure reads as flakiness in that one pipeline and can survive several sprints before anyone connects it to the group.
What the same workflow costs to run
Once the group grants access, the workflow above bills at the rates in the table. Assume the same 6 repositories at 8 runs per working day over 21 working days, rounded to 1,000 runs per month, with the test job at 6 minutes, package at 4 minutes, and deploy at 2 minutes:
teston warp-ubuntu-latest-x64-8x: 1,000 runs x 6 minutes x $0.016 = $96 per month.packageon warp-ubuntu-latest-arm64-8x: 1,000 runs x 4 minutes x $0.012 = $48 per month.deployon warp-ubuntu-latest-x64-4x: 1,000 runs x 2 minutes x $0.008 = $16 per month.- Total: $160 per month.
Set that against the model above. A full month of compute for this workflow costs $160, and one day of a runner group that blocks the same repositories costs about $1,600 in engineer time. Access configuration is worth an hour of attention during onboarding.
FAQ
Which runner group do WarpBuild runners join?
WarpBuild registers itself as a self-hosted runner in the Default runner group (id 1) of your GitHub organization. If your organization uses a different group, select it in the WarpBuild dashboard under Runners, then confirm that group grants access to the repository.
Why do my jobs never start in a public repository?
GitHub disables self-hosted runners in public repositories by default, including managed ones. Open the organization runner group settings page for group id 1 and check the Allow public repositories box. Every job in every public repository queues until that box is checked.
Can a runner group restrict which workflows use it?
Yes. GitHub restricts a group by workflow path, branch, sha, and tag. A restriction is written as a full path with a ref, for example monalisa/octocat/.github/workflows/cd.yaml@refs/heads/main, which allows only cd.yaml on main and queues every other workflow.
How do I tell a runner group block from a capacity problem?
A group block leaves the job queued with an empty log for as long as you let it sit, because no runner ever claims it. A capacity wait resolves once other jobs finish. Generally available WarpBuild Linux and Windows runners do not have plan-level concurrency caps, so check group access first when one of those jobs never starts.
Start with $10 in free credits
Change the runner label in your workflow and keep the rest of your GitHub Actions setup. Runner time is billed per minute.