Skip to content
Latchkey

npm "404 Not Found" for a Private Package - Fix in CI

A 404 for a package you know exists usually means npm asked the wrong registry - or asked anonymously, so a private package looks like it does not exist at all.

What this error means

npm install/npm ci fails with 404 Not Found - GET for a scoped/private package, while public packages resolve fine. The package is real; npm is just looking in the wrong place or without credentials.

npm output
npm error code E404
npm error 404 Not Found - GET https://registry.npmjs.org/@acme%2finternal-lib
npm error 404 '@acme/internal-lib@^1.2.0' is not in this registry.

Common causes

Scope not pointed at the private registry

Without @acme:registry=https://your-registry/, npm queries the public registry for the scoped package and gets a legitimate 404.

Anonymous request to a private registry

Some private registries return 404 (not 401) for unauthenticated reads to avoid leaking existence. No token means the package is invisible.

Typo in the package name or version

A wrong scope, name, or a version that was never published also produces a genuine 404.

How to fix it

Map the scope and authenticate

Point the scope at the right registry and supply a token.

Terminal
cat > .npmrc <<'EOF'
@acme:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=${NODE_AUTH_TOKEN}
EOF
NODE_AUTH_TOKEN="$REGISTRY_TOKEN" npm ci

Confirm the package exists as named

  1. Double-check the scope, name, and version against the registry.
  2. Verify the version in the lockfile was actually published.
  3. If it 404s only in CI, suspect missing scope mapping or token, not a missing package.

How to prevent it

  • Always map private scopes to their registry in .npmrc.
  • Provide CI tokens for private reads.
  • Pin published versions in the lockfile.

Related guides

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