Skip to content
Latchkey

semantic-release npm E401 verifying the registry in CI

The @semantic-release/npm plugin writes an .npmrc that reads ${NPM_TOKEN} and then verifies registry access. If NPM_TOKEN is empty or the .npmrc references the wrong variable, npm returns E401 Unauthorized during verification.

What this error means

The run fails with "npm ERR! code E401" and "Unable to authenticate, need: Basic realm" or "401 Unauthorized" while checking the registry.

semantic-release
npm ERR! code E401
npm ERR! 401 Unauthorized - GET https://registry.npmjs.org/-/whoami
npm ERR! need auth This command requires you to be logged in to https://registry.npmjs.org/

Common causes

NPM_TOKEN is not set for the step

The .npmrc the plugin writes references ${NPM_TOKEN}, which resolves to empty when the variable is not in the step env.

A custom .npmrc references a different variable

A committed .npmrc reads a token name that CI does not populate, so authentication is empty.

How to fix it

Set NPM_TOKEN in the step env

  1. Map the npm token to NPM_TOKEN in the release step.
  2. Let @semantic-release/npm write the .npmrc, or match your .npmrc to NPM_TOKEN.
  3. Re-run so the whoami/registry check authenticates.
.github/workflows/release.yml
- run: npx semantic-release
  env:
    NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
    GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Align a custom .npmrc with the token variable

If you commit an .npmrc, make its auth line read the same variable you set in CI.

.npmrc
//registry.npmjs.org/:_authToken=${NPM_TOKEN}

How to prevent it

  • Set NPM_TOKEN in the release step for any npm publish.
  • Keep committed .npmrc auth lines consistent with the CI variable.
  • Prefer letting @semantic-release/npm manage the .npmrc.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →