What This Error Means
npm received an authentication error (missing/invalid credentials) from the registry.
How to Fix It
- Check which registry npm is using:
npm config get registry. - If the package is scoped, verify scope registry mapping in
.npmrc(example:@your-scope:registry=...). - Confirm the registry identity:
npm whoami(it should print a username for that registry). - Login again:
npm logoutthennpm login(or set a token in.npmrcfor the correct host). - If you are using a scope, confirm the scope registry mapping in
.npmrcis correct. - If using GitHub Packages or a private registry, confirm the token has the correct scopes/permissions for that registry.
- Retry with logs:
npm --verbose(it shows which host returned 401/403).
Why It Happens
- Your
.npmrctoken is missing, expired, or scoped to the wrong registry host. - You are installing a private package but you are not authenticated for that scope/registry.
- The token is valid but lacks permission (forbidden) for the requested package or operation.
How to Verify
- Run
npm whoamiand confirm it succeeds. - Re-run the original command and confirm the registry no longer returns 401/403.
Manual authentication checks
- Print effective config:
npm config list -l(look for registry and auth entries). - Check
.npmrcprecedence (project, user, global) to ensure you are editing the right file.
Common CLI Output
npm ERR! code E401npm ERR! Incorrect or missing password How npm uses registry credentials
- npm sends requests to the configured registry using credentials from
.npmrc. - Registry hosts treat tokens differently (npmjs vs GitHub Packages vs private registries).
- A mismatched registry host/token pairing is a common cause of 401/403.
Prevention Tips
- Use dedicated tokens for CI and rotate them periodically.
- Keep
.npmrcregistry routing explicit for scoped packages. - Use a proxy/cache registry to reduce auth surprises between environments.
Where This Can Be Triggered
github.com/npm/cli/blob/417daa72b09c5129e7390cd12743ef31bf3ddb83/lib/utils/get-identity.js
This is a registry authentication call path. Auth errors like this code appear when the registry returns 401/403 for these endpoints. - GitHub
// No username, but we have other credentials; fetch the username from registry
if (creds.token || creds.certfile && creds.keyfile) {
const registryData = await npmFetch.json('/-/whoami', { ...opts })
if (typeof registryData?.username === 'string') {
return registryData.username
}