This error occurs when your npm authentication token has expired and can no longer authenticate requests to private registries. As of 2025, npm has strengthened security by enforcing token expiration limits.
The E401 "Token has expired" error means npm cannot authenticate your request to a private registry because your access token is no longer valid. Authentication tokens are credentials that prove your identity when accessing private npm packages or publishing to registries. Starting in 2025, npm implemented significant security changes. Classic tokens were permanently revoked on November 5, 2025, and new granular access tokens now have mandatory expiration limits: write tokens default to 7 days with a maximum of 90 days, while read-only tokens can last longer. This means tokens that worked indefinitely in the past now expire regularly. When npm attempts to install packages from a private registry or publish packages, it uses tokens stored in your .npmrc file. If that token has expired, exceeded its lifetime, or been revoked, the registry returns a 401 Unauthorized response, halting the operation.
For local development, the simplest fix is to re-authenticate with npm:
npm loginThis creates a new two-hour session token. You'll be prompted for:
- Username
- Password
- Email address
- Two-factor authentication code (if enabled)
Note: Session tokens expire after 2 hours for security, so you'll need to re-authenticate periodically.
For automated workflows (GitHub Actions, GitLab CI, Jenkins, etc.), create a long-lived granular access token:
Option 1: Using the CLI
npm token create --read-only # For installing packages
npm token create # For publishing (max 90 days)Option 2: Using the npm website
1. Go to https://www.npmjs.com/settings/[username]/tokens
2. Click "Generate New Token"
3. Choose "Granular Access Token"
4. Set expiration (max 90 days for write tokens)
5. Configure package access permissions
6. Copy the token immediately (shown only once)
Update your .npmrc or environment variables:
# .npmrc file
//registry.npmjs.org/:_authToken=${NPM_TOKEN}Store the token in your CI/CD secrets as NPM_TOKEN.
Invalid or corrupted .npmrc files cause authentication failures. Check and fix your configuration:
Locate your .npmrc:
# User-level (most common)
cat ~/.npmrc
# Project-level
cat .npmrcRemove old/invalid tokens:
# Delete the file to start fresh
rm ~/.npmrc
# Or edit to remove expired token lines
nano ~/.npmrcFor scoped packages, ensure registry is properly configured:
@yourscope:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=TOKEN_HEREAfter fixing .npmrc, clear cache and reinstall:
npm cache clean --force
rm -rf node_modules package-lock.json
npm installEliminate token expiration issues entirely by using OpenID Connect (OIDC) authentication:
GitHub Actions example:
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
registry-url: 'https://registry.npmjs.org'
- name: Publish package
run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}Benefits:
- No long-lived tokens to manage or rotate
- Tokens are generated automatically per job
- Scoped to specific packages and operations
- Automatically expire after job completes
Setup trusted publishing:
1. Go to https://www.npmjs.com/package/[package-name]/access
2. Enable "Trusted publishing"
3. Configure your CI provider (GitHub, GitLab, etc.)
4. Remove hard-coded tokens from your workflows
If using third-party private registries, follow their renewal process:
GitHub Packages:
# Use a personal access token with package permissions
echo "//npm.pkg.github.com/:_authToken=YOUR_PAT" >> ~/.npmrcGenerate new PAT at: https://github.com/settings/tokens
Azure DevOps:
1. Navigate to User Settings > Personal Access Tokens
2. Check expiration date of existing tokens
3. Create new token with "Packaging (Read & Write)" scope
4. Update .npmrc:
registry=https://pkgs.dev.azure.com/ORG/_packaging/FEED/npm/registry/
always-auth=true
//pkgs.dev.azure.com/ORG/_packaging/FEED/npm/registry/:username=anything
//pkgs.dev.azure.com/ORG/_packaging/FEED/npm/registry/:_password=[BASE64_ENCODED_PAT]
//pkgs.dev.azure.com/ORG/_packaging/FEED/npm/registry/:email=anythingJFrog Artifactory:
# Re-authenticate with JFrog CLI
jf rt loginToken Security Best Practices
With npm's 2025 security changes, managing token lifecycles is critical:
1. Use the minimum required permissions: Create read-only tokens for installing packages, write tokens only when publishing.
2. Rotate tokens proactively: Don't wait for expiration. Set calendar reminders to rotate tokens every 30-60 days.
3. Use different tokens per environment: Separate tokens for CI/CD, local development, and team members improve security and make revocation easier.
4. Audit token usage: Regularly review active tokens at https://www.npmjs.com/settings/~/tokens and revoke unused ones.
5. Environment-specific configurations: Use .npmrc files wisely:
- Project-level .npmrc: Registry configuration only (no tokens!)
- User-level ~/.npmrc: Personal tokens for local development
- CI secrets: Tokens injected via environment variables
Why npm made these changes: The npm registry experienced several supply chain attacks where compromised accounts with long-lived tokens were used to inject malicious code into popular packages. Token expiration limits reduce the window of opportunity for attackers.
Migration from classic tokens: If you're still using workflows that expect classic tokens (revoked November 2025), you must update them to use granular access tokens or trusted publishing. Classic tokens cannot be recreated.
Debugging authentication issues: Enable verbose logging to see exactly which registry npm is trying to authenticate with:
npm install --loglevel=verboseLook for lines like "authorization:", "token:", or "registry:" to diagnose configuration problems.
npm ERR! code EAI_NODATA npm ERR! errno EAI_NODATA npm ERR! getaddrinfo EAI_NODATA registry.npmjs.org
How to fix "npm ERR! code EAI_NODATA - getaddrinfo EAI_NODATA"
npm ERR! code EMPTYPACKAGE npm ERR! Package contains no files
How to fix 'npm ERR! code EMPTYPACKAGE' - Package contains no files
npm ERR! code EWORKSPACEMISSING npm ERR! Workspace does not exist: packages/missing
How to fix "npm ERR! code EWORKSPACEMISSING - Workspace does not exist" error
npm ERR! code EADDRNOTAVAIL npm ERR! errno EADDRNOTAVAIL npm ERR! Address not available
How to fix "npm ERR! code EADDRNOTAVAIL - Address not available" error
npm ERR! code CERT_SIGNATURE_FAILURE npm ERR! Certificate signature failure
How to fix 'npm ERR! code CERT_SIGNATURE_FAILURE' certificate signature failure