1309 words
7 minutes

actions/checkout v5: Fix Node 24 Runner Errors Safely

2026-08-13
2026-09-25
DevOps
GitHub Actions
/
CI/CD
/
DevOps
/
Migration

If a workflow starts failing after changing to actions/checkout@v5, check the Actions Runner before rewriting the YAML. Checkout v5 uses the Node 24 action runtime and requires Actions Runner v2.327.1 or newer. That requirement is especially easy to miss on self-hosted machines, because the workflow file and the runner are upgraded separately.

The safe migration is small: update the action reference, confirm every runner that can receive the job meets the minimum version, then run a workflow that exercises the same checkout options your production jobs use.

GitHub removed Node 20 from its runners on 2026-09-23, so the temporary ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION opt-out no longer works. Runners now use Node 24 for JavaScript actions. This platform-wide cutoff is separate from checkout v5’s minimum Runner v2.327.1: check both the runner application and the action named in the error. Node 24 also excludes self-hosted runners on macOS 13.4 or earlier and ARM32; see the Node 24 self-hosted runner guide for that host boundary.

What changed in checkout v5#

The checkout v5.0.0 release moved the action to Node 24 and lists v2.327.1 as the minimum compatible runner. The checkout README repeats that boundary.

This is an action-runtime change, not a new checkout input. Settings such as fetch-depth, fetch-tags, submodules, sparse-checkout, and persist-credentials keep their own meanings. Do not remove them just because the major version changed.

Choose the checkout version before migrating#

actions/checkout@v5 is still the version this error points to, but it is not the current upstream release. The checkout README currently documents v7, so treat the runner fix and the version upgrade as separate decisions:

VersionBoundary to verifyDecision
checkout@v5Node 24 action runtime; minimum Actions Runner v2.327.1; the floating @v5 tag includes the fork-PR guard from v5.1.0Upgrade the runner first when you must keep v5, then check privileged fork-PR workflows for the new guard.
checkout@v6Credentials move to a separate file under $RUNNER_TEMP; authenticated Git commands from a Docker container action require Actions Runner v2.329.0 or newer; v6.1.0 includes the fork-PR guardTest this path when the workflow runs Git commands inside a container or depends on credential-file details.
checkout@v7Current upstream release at the 2026-09-25 check is v7.0.1; the fork-PR guard was introduced in v7.0.0Audit privileged workflows before moving to v7. For the trust-model decision, see the fork pull request safety guide.

The guard is not a v7-only change. GitHub backported it to supported major lines on 2026-07-20: v2.8.0, v3.7.0, v4.4.0, v5.1.0, and v6.1.0; v7.0.0 already included it. A floating major reference such as actions/checkout@v5 receives the backport, but a pinned minor, patch, or commit SHA does not move automatically. If checkout starts failing only for fork pull requests after a tag update, check the trigger and ref before treating it as a Node 24 runner error.

Do not jump from a v5 runner error to a blanket action upgrade. First prove the runner version, then choose the version whose security and container behavior matches the workflow.

The smallest workflow diff is usually:

steps:
- name: Check out repository
uses: actions/checkout@v5

If the existing workflow has with: options, keep them while making the version change:

- uses: actions/checkout@v5
with:
fetch-depth: 0
persist-credentials: false

fetch-depth: 0 is still an intentional choice for workflows that need tags or full history. It is not required for Node 24 compatibility.

Check the runner before changing more code#

GitHub-hosted runners are maintained by GitHub, but self-hosted runners are part of your infrastructure. Check the version of every eligible self-hosted runner, not only the machine you used for a local test. A label can route the same job to an older machine on the next run.

You can inspect runner versions in the repository or organization Actions settings. With suitable read permission, the REST API also exposes each runner’s version:

Terminal window
gh api --paginate repos/OWNER/REPO/actions/runners \
--jq '.runners[] | [.name, .os, .architecture, .status, .busy, .version] | @tsv'

Replace OWNER/REPO and treat the output as inventory data. Do not paste registration tokens or other credentials into a bug report. If the runner is below 2.327.1, upgrade the runner application using the installation instructions for its operating system, then wait for it to reconnect before testing checkout v5.

The self-hosted runner documentation is the right place to check the runner’s update and platform requirements. An action’s Node runtime support and the host’s operating-system support are separate checks; the Node 24 runner troubleshooting guide covers that wider boundary.

Verify the migration with a representative job#

Use a branch or a low-risk workflow first. The test should cover the real behavior that follows checkout, not only whether the action step turns green.

  1. Confirm the job is scheduled on the runner class you intend to upgrade.
  2. Run actions/checkout@v5 with the same ref, history depth, submodule, or sparse-checkout settings used in production.
  3. Check that the next step can read the expected files and, when needed, tags or commit history.
  4. Run the workflow on every self-hosted label that can receive the production job.
  5. Keep the workflow diff and runner upgrade in the same change record so a future rollback is understandable.

For a diagnostic workflow, printing non-secret runner metadata can make the boundary visible:

- name: Show runner boundary
shell: bash
run: |
echo "runner=${RUNNER_NAME}"
echo "os=${RUNNER_OS} arch=${RUNNER_ARCH}"
- uses: actions/checkout@v5

The checkout action does not turn a shallow clone into a full clone. If a later step runs git describe, compares branches, or reads tags, validate those inputs explicitly instead of attributing the failure to the Node runtime.

Common failure paths#

The job says the Node 24 runtime is unsupported#

Inspect the runner version first. Changing runs-on only changes the label requested by the job; it does not update a self-hosted runner behind that label. Upgrade the runner or temporarily route the job to a maintained runner class while the host upgrade is scheduled.

Only one runner fails#

Compare the runner version, operating system, architecture, and labels for the passing and failing machines. A mixed runner fleet can make the same workflow appear flaky when the action is deterministic.

A fork pull request fails after checkout updates#

The backported guard rejects a fork pull request when repository points to the fork or ref resolves to its head or merge commit. It applies to pull_request_target and to workflow_run runs whose original event was a pull_request* event. Same-repository pull requests and the pull_request trigger are unchanged. This can affect a floating @v5 tag even when the workflow did not move to v7; pinned minor, patch, and SHA references need an explicit update to receive the backport.

Before opting out, confirm the privileged trigger is necessary and that checked-out code is never executed. GitHub recommends using pull_request when the workflow does not need secrets or elevated permissions. Only then consider allow-unsafe-pr-checkout: true, following GitHub’s secure pull_request_target guidance.

Checkout succeeds but later Git commands fail#

Review the checkout inputs. Full history, tags, credentials, and submodules are independent of the Node 24 migration. For a workflow that must not leave the token in local Git configuration, keep persist-credentials: false and authenticate later with a deliberately scoped method.

You need an immediate rollback#

If an old runner cannot be upgraded during an incident window, pin the workflow to the previously working checkout major version as a short-lived rollback, record the reason, and schedule the runner update. Do not treat a rollback as evidence that v5’s checkout inputs are incompatible with the repository.

FAQ#

Does checkout v5 need Node 24 installed on my host?#

The important boundary is the Actions Runner’s ability to launch the action runtime. Check the runner version and the host requirements rather than installing an unrelated system-wide Node version.

Do I need to change fetch-depth for v5?#

No. Keep the existing value unless the workflow’s Git history requirements changed. fetch-depth: 0 is for all history, tags, and branch comparisons; it is not a v5 migration step.

Why did the migration pass on GitHub-hosted runners but fail on my server?#

The runner application is maintained differently. A self-hosted label can point at an older runner, so compare the reported versions before comparing application code.

References:

actions/checkout v5.0.0 release

actions/checkout v5.1.0 release

actions/checkout README

actions/checkout v6.0.0 release

actions/checkout v6.1.0 release

actions/checkout v7.0.0 release

actions/checkout v7.0.1 release

GitHub Changelog: Safer pull_request_target defaults for checkout

GitHub Changelog: Node 20 is no longer available in GitHub Actions

About self-hosted runners

actions/checkout v5: Fix Node 24 Runner Errors Safely
https://laplusda.com/en/posts/github-actions-checkout-v5-node24-migration/
Author
Zero
Published at
2026-08-13
License
CC BY-NC-SA 4.0