The Problem
Few things disrupt a workflow faster than an authentication error during a production build. A 401 Unauthorized error is the registry's way of saying it doesn't recognize your credentials. Either your npm client is sending an invalid token, or it isn't sending one at all.
npm ERR! code E401
npm ERR! 401 Unauthorized - GET https://registry.npmjs.org/@scope/package - You must be logged in to install this package.
Youโll usually see this when working with private scoped packages, such as @mycompany/internal-tool. However, it can also happen with public packages if your local session has expired or your .npmrc file contains conflicting settings.
Step 1: Verify Your Current Identity
Start by checking who npm thinks you are. Run this command in your terminal:
npm whoami
If the terminal returns a 401 error or says "this command requires you to be logged in," your session is dead. If it returns the wrong username, you are likely logged into a personal account instead of a corporate one. This is a common slip-up when developers juggle multiple projects.
Step 2: Refresh Your Session
The most reliable fix is to cycle your login. This process flushes the old token and writes a fresh one to your global configuration. Many tokens expire automatically after 30 days of inactivity, so a quick refresh often solves the issue.
npm logout
npm login
Note that if you are using a third-party registry like GitHub Packages or Artifactory, you must include the registry flag. For example, GitHub requires:
npm login --registry=https://npm.pkg.github.com
Step 3: Audit Your .npmrc Configuration
If logging in fails, your configuration files likely have a conflict. npm looks for .npmrc files in two main places: your home directory and your project root. Project-level settings always win the priority war.
The Global .npmrc
On macOS or Linux, find this at ~/.npmrc. Windows users will find it at C:\Users\<Username>\.npmrc. Open it and look for lines resembling this:
//registry.npmjs.org/:_authToken=npm_xxxxxxxxxxxx
Check for duplicates. If you have three different tokens for the same registry, npm might be sending the wrong one. For scoped packages, ensure the mapping is explicit:
@mycompany:registry=https://registry.npmjs.org/
//registry.npmjs.org/:_authToken=your-36-character-token
The Project-Level .npmrc
Check your project root for a local .npmrc. If this file points to a specific registry but lacks an auth token, npm will ignore your global credentials. This results in a 401 error even if you are logged in globally.
Step 4: Fix CI/CD and Automation Errors
Automation environments like GitHub Actions or GitLab CI cannot handle interactive logins. You must use environment variables. A common mistake is hardcoding a token that eventually expires.
Ensure your project's .npmrc is configured to read from the environment dynamically:
//registry.npmjs.org/:_authToken=${NPM_TOKEN}
Verify that NPM_TOKEN is defined in your CI secrets. If the variable is missing or empty, npm literally sends the string "${NPM_TOKEN}" to the server. The registry will promptly reject this with a 401.
Step 5: Clear the Cache and Reinstall
Sometimes npm persists an unauthorized state in its local metadata cache. If your credentials are correct but the error remains, it's time to clear the deck. Force a cache clean to remove any stale headers:
npm cache clean --force
Follow this by deleting your local artifacts to ensure a clean slate:
rm -rf node_modules package-lock.json
npm install
How to Verify the Fix
Run these three checks to confirm your setup is healthy:
- Identity Check:
npm whoamishould return your username instantly. - Metadata Check: Try
npm view @scope/package-name. If you see a JSON object with version numbers, your authentication is successful. - Installation: Run
npm install. If the CLI moves past the "idealTree" phase, the handshake is complete.
Troubleshooting Tips
- Two-Factor Authentication (2FA): Ensure your npm CLI is version 9 or higher. Older versions often fail to trigger the 2FA prompt, leading to silent 401 errors.
- Corporate Proxies: If you are behind a firewall, your
proxysettings innpm config listmight be stripping theAuthorizationheader. Check with your network team. - Token Scoping: When generating a manual token, ensure it has "Read" permissions. A token restricted to "Publish only" will fail during a standard
npm install.

