Skip to content
Latchkey

Nexus npm "npm ERR! 401 Unauthorized" on publish in CI

npm sent no valid credential to the Nexus npm registry, so Nexus returned 401. Nexus expects a base64 user:password in _auth (or an npm token) scoped to the hosted npm repository URL.

What this error means

npm publish or npm install against the Nexus registry fails with "npm ERR! code E401" and "npm ERR! 401 Unauthorized - PUT https://nexus.example.com/repository/npm-hosted/...".

npm
npm ERR! code E401
npm ERR! 401 Unauthorized - PUT
https://nexus.example.com/repository/npm-hosted/@acme%2fapp - Unauthorized

Common causes

No auth token in .npmrc for the registry

The CI .npmrc points at the Nexus registry but has no _auth or //host/repository/npm-hosted/:_authToken, so npm publishes anonymously and gets 401.

Wrong auth encoding for a Nexus npm repo

Nexus npm expects base64 of username:password in _auth; a plaintext password or a token for a different repo will not authenticate.

How to fix it

Write a credentialed .npmrc from secrets

  1. Base64-encode the Nexus username:password into an _auth value.
  2. Write .npmrc in CI with the registry URL and _auth from secrets.
  3. Publish so npm sends the Authorization header.
.npmrc
registry=https://nexus.example.com/repository/npm-hosted/
_auth=${NEXUS_NPM_AUTH_B64}
always-auth=true
email=ci@example.com

Generate the base64 auth in the pipeline

Compute _auth from CI secrets so the password is never committed.

Terminal
echo -n "$NEXUS_USERNAME:$NEXUS_PASSWORD" | base64

How to prevent it

  • Keep NEXUS_USERNAME/NEXUS_PASSWORD in CI secrets and derive _auth at runtime.
  • Set always-auth=true so reads and writes both authenticate.
  • Publish to the hosted npm repo URL, not a group/proxy.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →