npm .npmrc Auth Token in CI - Configure Registry Credentials Safely
Private installs need an _authToken in .npmrc. In CI the token must come from a secret and the variable in .npmrc must actually expand, or npm sends the literal placeholder and auth fails.
What this error means
Private package installs fail with 401/403, or npm sends the unexpanded token placeholder verbatim because the .npmrc variable was never expanded by the shell or by npm config.
npm
npm ERR! code E401
npm ERR! 401 Unauthorized - GET https://registry.npmjs.org/@acme%2fui
npm ERR! authToken in .npmrc: ${NPM_TOKEN} (not expanded)Common causes
The token variable was not expanded
A committed .npmrc referencing an env-var token is only expanded when the value is written via the shell or npm config sees the env var; otherwise the literal placeholder string is sent.
No token secret is available in CI
The workflow never injects the token, so .npmrc has no usable credential.
How to fix it
Write the token from a secret at runtime
- Expose the token as an env var from a secret.
- Write the expanded value into .npmrc before install.
Terminal
echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" >> .npmrcPass the secret through the env
- Reference the repo secret in the step env block.
- Never commit the raw token to .npmrc.
Workflow
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}How to prevent it
- Keep the token in CI secrets, write or expand it into .npmrc at runtime, and add .npmrc token lines to .gitignore so a credential never lands in source control.
Related guides
npm .npmrc _authToken Not Expanded - Fix Literal ${TOKEN} in CIFix npm .npmrc _authToken auth failures in CI - a ${NPM_TOKEN} placeholder left literal because the env var i…
npm E401 / E403 Private Registry Auth in CI - Fix Registry AuthenticationFix npm E401 and E403 authentication errors against a private registry in CI by configuring a valid auth toke…
npm 403 Forbidden on Publish in CI - Fix Publish Permission ErrorsFix npm 403 Forbidden errors when publishing in CI, caused by a bad token, a taken name, a missing version bu…