Fix npm E401 401 Unauthorized errors when installing or publishing. Caused by expired tokens or bad .npmrc auth. Step-by-step fix here.
The E401 Unauthorized error in npm indicates that the registry rejected your authentication credentials. This happens when npm sends a request to download or publish a package, but the authentication token is missing, expired, or invalid. When you run `npm install` or `npm publish`, npm reads authentication credentials from your `.npmrc` file (located in your home directory or project folder) and includes them in requests to the registry. If these credentials are wrong or have expired, the registry returns a 401 Unauthorized response. This error commonly appears after password resets, when access tokens expire, when switching between registries (public npm vs private registries like Azure Artifacts, GitHub Packages, or Verdaccio), or when CI/CD pipelines have stale credentials.
First, check if you're currently logged in to npm:
npm whoamiIf this returns an error like ENEEDAUTH or E401, you're not authenticated. If it returns a username, your credentials exist but may be expired or invalid for the specific registry.
Also check which registry npm is configured to use:
npm config get registryThe default public registry is https://registry.npmjs.org/.
Clear your current authentication and log in fresh:
npm logout
npm loginFollow the prompts to enter your npm username, password, and email. For accounts with 2FA enabled, you'll also need to enter a one-time password.
After logging in, verify it worked:
npm whoamiThe .npmrc file stores your authentication tokens. Check all locations for stale tokens:
On macOS/Linux:
cat ~/.npmrcOn Windows:
type %USERPROFILE%\.npmrcLook for lines containing _authToken or _auth. If you see old tokens, remove them:
# Remove the stale token line, or delete the file entirely:
rm ~/.npmrcThen run npm login again to regenerate valid credentials.
Also check for a project-level .npmrc that might have stale tokens:
cat .npmrc # In your project directoryIf you recently upgraded npm or switched registries, your package-lock.json may contain resolved URLs that no longer match your .npmrc configuration:
rm package-lock.json
npm installThis forces npm to resolve all packages fresh with your current registry and credentials.
Note: If you use a lockfile for reproducible builds, commit the new package-lock.json after it's regenerated.
If your registry configuration is incorrect, reset it to the public npm registry:
npm config set registry https://registry.npmjs.org/Then try your command again. If you need a private registry, ensure you configure both the registry URL and authentication token correctly.
In some cases, cached authentication data can cause issues:
npm cache clean --forceThen retry your npm command.
For automated environments, use access tokens instead of logging in interactively.
Generate a token on npmjs.com:
1. Go to https://www.npmjs.com/settings/~/tokens
2. Click "Generate New Token"
3. Choose "Granular Access Token" (recommended) or "Classic Token"
4. Set appropriate permissions and expiration
Add the token to your .npmrc:
//registry.npmjs.org/:_authToken=YOUR_TOKEN_HEREOr use an environment variable (recommended for CI/CD):
//registry.npmjs.org/:_authToken=${NPM_TOKEN}Then set NPM_TOKEN as a secret in your CI/CD platform.
### Private Registry Authentication
For private registries (Azure Artifacts, GitHub Packages, JFrog Artifactory, Verdaccio), each has its own authentication method:
Azure Artifacts:
# Install the credential helper
npm install -g vsts-npm-auth
# Authenticate (creates/updates .npmrc)
vsts-npm-auth -config .npmrc
# Force re-authentication if tokens expired
vsts-npm-auth -config .npmrc -FGitHub Packages:
# In .npmrc
//npm.pkg.github.com/:_authToken=YOUR_GITHUB_PAT
@your-org:registry=https://npm.pkg.github.com### Token Expiration
- Legacy npm tokens never expired, but they were removed on November 5, 2025
- Granular access tokens can have custom expiration (1 day to 1 year)
- Azure DevOps PATs expire by default (max 1 year)
- Set calendar reminders to rotate tokens before expiration
### Scoped Packages
If the error only occurs for scoped packages (@company/package-name), you may need registry configuration specific to that scope:
# Route @company packages to private registry
npm config set @company:registry https://npm.company.com/
# Set auth for that registry
//npm.company.com/:_authToken=TOKEN### Debugging Authentication Issues
Enable verbose logging to see exactly where authentication fails:
npm install --loglevel verboseOr check the npm debug log:
cat ~/.npm/_logs/*-debug.log### Two-Factor Authentication
If your npm account has 2FA enabled and you're publishing, you'll need to provide a one-time password:
npm publish --otp=123456For automation, use an access token with appropriate permissions - 2FA is not required when using tokens.
npm notice access token expired or revoked. Please try logging in again.
Token has expired - npm authentication failure
npm ERR! code EAI_AGAIN
How to fix "EAI_AGAIN" in npm
npm error code E403 npm error 403 Forbidden - PUT https://registry.npmjs.org/<package>
How to fix 'E403 Forbidden' error in npm
npm ERR! code EUSAGE npm ERR! Usage error
How to fix "npm ERR! code EUSAGE" in Node.js projects
npm ERR! DEPTH_ZERO_SELF_SIGNED_CERT
How to fix "DEPTH_ZERO_SELF_SIGNED_CERT" in npm