セルフホストランナーがIdleなのにジョブを拾わない原因と対処|Waiting for a runner to pick up this job
セルフホストランナーで動かしている GitHub Actions のジョブが、Waiting for a runner to pick up this job... のまま進まなくなっていませんか?
設定画面でランナーを見ると、緑の Idle(待機中)と表示されています。
ランナーは空いているのに、ジョブだけが拾われない状態です。
ラベルもランナーグループも正しく、ランナーのログにもエラーは出ません。
原因は、GitHub が 2026-09-29 から全面適用したセルフホストランナーの最低バージョンの強制でした。
私の組織では、自動更新を有効にしていたランナー 4 台が、すべて 2.328.0 で止まっていました。
この記事では、バージョンの確認方法と手動での更新手順、止まる前に期限を検知する REST API の使い方をまとめます。
Idle のまま「Waiting for a runner to pick up this job」で止まる症状
私の環境で起きていたのは、次の状態です。
- ジョブが
Queuedのまま、Waiting for a runner to pick up this job...から進まない - 組織の Settings → Actions → Runners では、対象のランナーは Idle(緑)
- ジョブの
runs-onのラベルも、ランナーグループの設定も正しい - ランナーのサービスは動いていて、
_diagのログにもバージョンが古いことを示すメッセージは見当たらない
このエラー文で検索すると、ラベルの不一致やランナーのオフラインといった原因がたくさん出てきます。
ところが今回は、そのどれにも当てはまりませんでした。
画面上は正常に見えるので、設定ミスを疑って時間を使ってしまいやすいのが厄介なところです。
ラベルとオンライン状態を確かめても原因が見つからないなら、次に疑うのはランナーのバージョンです。
原因: 2026-09-29 から始まった最低バージョンの強制
GitHub は 2026-06-12 に、セルフホストランナーのバージョン要件を強制する計画を告知しました。
開始日は一度動いていて、github.com(GitHub Enterprise Cloud)では当初の 9 月 25 日から 2026-09-29(火)に変わったうえで全面適用されています。
- GitHub Enterprise Cloud: 2026-09-29 から全面適用
- データレジデンシー版の GitHub Enterprise Cloud: 2026-07-31 から全面適用
- GitHub Enterprise Server: 告知の対象外
登録の条件と、ジョブを実行する条件は別
注意したいのは、「登録できる最低バージョン」と「ジョブを実行できる最低バージョン」が別だという点です。
| 対象 | 条件 | 満たさないと |
|---|---|---|
| 登録・再登録 | 2.329.0 以上 | ランナーを登録できない |
| ジョブの実行 | 新しいリリースを公開から 30 日以内に入れ続ける | ジョブを拾わない |
告知には、次の一文があります。
A runner pinned to 2.329.0 that never updates again will not pick up jobs.登録の条件を満たしていても、更新を止めたランナーはいずれジョブを拾わなくなるということです。
告知に書かれているのは「ジョブがキューに残ったままになるか、失敗する」までで、画面の表示がどうなるかは書かれていません。
私の環境では、それが「Idle のまま待たされる」という見た目で現れました。
ランナーのバージョンを確認する
ランナーのバージョンは、サービスの状態から確認できます。
cd ~/actions-runner
sudo ./svc.sh status
# ログの中に次の行が出る
# Current runner version: '2.328.0'私のランナーは 2.328.0 で、登録の最低バージョンの 2.329.0 にすら届いていませんでした。
その時点で最新だった 2.337.0 へ手動で上げると、ログに Listening for Jobs が出た3 秒後に、待たされていたジョブを拾いました。
設定は何も変えていないので、原因はバージョンだったと判断できます。
自動更新が有効なのに、なぜ古いままだったのか
告知では、自動更新が有効なランナーは「更新サービスに届く限り」30 日の条件を自動で満たすとされています。
私のランナーも、自動更新を無効にはしていませんでした(--disableupdate は付けていない)。
ところが、ランナーのディレクトリに残っている更新の記録を見ると、最後の自動更新は 2025-10-05(2.320.0 → 2.328.0)でした。
同じ組織の別のランナーも調べると、4 台すべてがちょうど 2.328.0 で止まっていました。
次のリリースの 2.329.0 は 2025-10-14 の公開で、告知では「新しい基盤がランナーを認識して接続を許すための最低バージョン」と説明されています。
そのため、この基盤の切り替えのところで、自動更新の連鎖が途切れたのではないかと私は見ています。
ただし、これは日付の並びからの推測で、GitHub の公式な説明は見つけられていません。
「自動更新を有効にしているから大丈夫」とは言い切れないので、設定ではなく実際に動いているバージョンを確認してください。
対処: ランナーを手動で更新する
Linux(x64)のランナーを、systemd のサービスとして動かしている場合の手順です。
バージョンとアーキテクチャは、actions/runner のリリースページで最新のものに読み替えてください。
cd ~/actions-runner
# 1. サービスを止める
sudo ./svc.sh stop
# 2. 登録情報をバックアップする(.runner_migrated は無い環境もある)
mkdir -p ~/runner-backup
cp -p .runner .credentials* .env .path .service ~/runner-backup/
cp -p .runner_migrated ~/runner-backup/ 2>/dev/null || true
# 3. 新しい版を取得し、リリースページに載っている SHA-256 と照合する
VERSION=2.337.0
curl -o actions-runner-linux-x64-${VERSION}.tar.gz -L \
https://github.com/actions/runner/releases/download/v${VERSION}/actions-runner-linux-x64-${VERSION}.tar.gz
echo "<リリースページの SHA-256> actions-runner-linux-x64-${VERSION}.tar.gz" | sha256sum -c
# 4. 既存のディレクトリに上書きで展開する
tar xzf ./actions-runner-linux-x64-${VERSION}.tar.gz
# 5. サービス用のスクリプトに差分がないかを見る
diff runsvc.sh bin/runsvc.sh
# 6. サービスを起動する
sudo ./svc.sh start手順の中で気を付けたい点は 3 つです。
- 再登録は不要でした。登録情報(
.runnerや.credentials)は展開しても上書きされません。バックアップは万一に備えたものです - 私のランナーでは、
binとexternalsがbin.2.328.0のような旧版のディレクトリへのシンボリックリンクになっていました。GNU tar で展開すると、リンクが普通のディレクトリに置き換わります。bin.2.328.0などは残るので、切り戻しにも使えます - サービスが実際に呼ぶ
runsvc.shは、展開しても更新されません。bin/runsvc.shとの差分を見て、差があれば反映を検討してください(2.337.0では差分はありませんでした)
起動後に sudo ./svc.sh status で Current runner version が新しい版になり、Listening for Jobs が出ていれば完了です。
再発を防ぐには: Online の監視では気付けない
今回の状態は、ランナーが Online かどうかの監視では検知できません。
画面上は Idle で、REST API でも status は online なので、死活監視は正常と判断します。
しかも「30 日以内に更新」のルールがあるので、一度直しても、次のリリースから 30 日経てばまた同じことが起きえます。
たとえば 2.338.0 は 2026-10-06 に公開されたので、2.337.0 で止めたランナーは、そこから 30 日のうちに上げる必要があります。
REST API でバージョンと期限を確認する
GitHub には、ランナーのバージョンごとの期限を返す REST API があります。
まず、組織のランナーの一覧から、各ランナーのバージョンを取ります。
gh api --paginate /orgs/ORG/actions/runners \
--jq '.runners[] | [.name, .status, .version] | @tsv'次に、そのバージョンの期限を問い合わせます。
gh api /orgs/ORG/actions/runners/deprecations/2.337.0リポジトリ単位で登録したランナーなら、/repos/OWNER/REPO/actions/runners/deprecations/VERSION で同じ情報を取れます。
返ってくる項目は次の 3 つです。
runner_version— 問い合わせたバージョンregistration_deprecates_at— このバージョンで登録できなくなる日時(未定ならnull)runtime_deprecates_at— このバージョンでジョブを実行できなくなる日時(未定ならnull)
runtime_deprecates_at を監視すれば、止まる前に気付けます。
私は、毎日 GitHub ホストのランナー(ubuntu-latest)でこの 2 つの API を呼び、期限が 14 日以内に迫ったら Slack に通知する workflow を作りました。
監視対象のセルフホストランナーが止まっていても動くように、監視自体は GitHub ホストのランナーで動かすのがポイントです。
なお、新しい版が出た直後は、1 つ前の版の runtime_deprecates_at がまだ null のことがあります(2.338.0 公開の翌日に 2.337.0 を問い合わせたときがそうでした)。
null を「期限なし」と扱わず、新しいリリースの公開日から 30 日を数えるチェックも併せておくと安心です。
GitHub App で呼ぶときの権限
この 2 つの API には、組織の管理者相当の権限が要ります(PAT(classic)なら admin:org スコープ)。
workflow から GitHub App のトークンで呼ぶ場合は、組織の権限の Self-hosted runners を Read(読み取り)だけ付ければ呼べます。
Write(書き込み)を付けるとランナーの登録用トークンも発行できてしまうので、読み取りに留めておくのが安全です。
actions/create-github-app-token を使うなら、発行するトークンの権限も絞れます。
- name: Generate App token
id: app-token
uses: actions/create-github-app-token@v3
with:
client-id: ${{ vars.APP_CLIENT_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
owner: ${{ github.repository_owner }}
permission-organization-self-hosted-runners: readPAT から GitHub App トークンへ切り替える手順は、PAT を GitHub App トークンに置き換える手順と 3 つの落とし穴もあわせてどうぞ。
起動時間が短いランナーは特に注意
コスト削減のために、決まった時間だけ EC2 を起動しているランナーもあると思います。
私の環境にも週に 1 時間だけ起動するランナーがあり、これも 2.328.0 のままでした。
手動で上げる前に起動して 8〜11 分待ってみましたが、自動更新は始まりませんでした。
起動している時間が短いランナーは、自動更新を受け取る機会そのものが少なくなります。
「30 日以内」のルールと組み合わせると気付かないうちに期限を過ぎやすいので、起動時に最新版へ上げる仕組みか、上の API による監視を優先して入れてください。
まとめ
- セルフホストランナーが Idle なのに
Waiting for a runner to pick up this job...のままなら、まずランナーのバージョンを疑う - GitHub Enterprise Cloud では 2026-09-29 から、登録は 2.329.0 以上、ジョブの実行は新リリースを 30 日以内に入れ続けることが強制されている
- 自動更新を有効にしていても、2.328.0 で更新が止まっていた実例がある。設定ではなく、実際のバージョンを確認する
- 手動更新は、サービスを止めて上書きで展開するだけで、再登録は不要だった
- Online の監視では気付けない。
/orgs/{org}/actions/runners/deprecations/{version}のruntime_deprecates_atで期限を監視する
セルフホストランナーは、一度動き始めると存在を忘れがちです。
ですが、強制が始まった以上は「放置すると 30 日で止まりうるもの」として扱う必要があります。
同じ症状で困っている方は、まず Current runner version を確認してみてください。
参考(出典)
- GitHub Actions: Minimum version enforcement timeline for self-hosted runners(GitHub Changelog)
- Self-hosted runner version enforcement date has moved(GitHub Changelog)
- REST API endpoints for self-hosted runners(GitHub Docs)
- actions/runner Releases(GitHub)
