Introduction
actions/setup-node resolves a Node.js version from the workflow input, a version file, or the hosted tool cache. When that version cannot be found, the job fails before dependency installation or tests even start. The most common causes are EOL Node versions, malformed version syntax, or self-hosted runners that cannot fetch or cache the requested release.
Symptoms
actions/setup-nodefails withVersion X was not found- The workflow works locally with
nvm, but CI cannot install the same version - A self-hosted runner fails while GitHub-hosted runners succeed
- Renovation or framework upgrades changed the requested Node version and broke the pipeline
Common Causes
- The workflow requests an end-of-life Node.js version no longer available from the action
node-versionornode-version-filepoints to an invalid or unexpected value- A self-hosted runner cannot download the Node release because of network or cache configuration
- Different parts of the repo disagree on the required Node version
Step-by-Step Fix
- 1.Inspect where the version request actually comes from
- 2.Check the workflow YAML,
.nvmrc,.node-version, andpackage.jsonso you fix the real source of truth instead of editing only one layer.
- uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"- 1.Replace EOL or malformed versions with a supported LTS release
- 2.Avoid loose or surprising syntax. For most repositories, an explicit current LTS release is the safest choice.
- uses: actions/setup-node@v4
with:
node-version-file: ".nvmrc"- 1.Verify self-hosted runner cache and outbound access
- 2.If the runner is self-hosted, confirm it can download Node releases and that any local tool cache is writable and consistent.
node -v
npm -v- 1.Retest with one known-good version before restoring matrices
- 2.If a matrix build requests several versions, prove a single stable version works first, then add additional supported versions back deliberately.
Prevention
- Keep one source of truth for the Node version, preferably
.nvmrcor.node-version - Plan Node LTS upgrades before the requested version reaches EOL
- Test self-hosted runners after proxy, firewall, or image changes
- Avoid version drift between workflow files, local development, and package engine constraints