Bun install 401 from a private registry (bunfig.toml token) in CI
Bun reached your private registry but was rejected: 401 means no valid token was sent, 403 means the token authenticated but cannot read the package. The registry is up; the auth in bunfig.toml is the problem.
What this error means
bun install fails with a 401/403 for a scoped package while public packages install fine, usually because the registry token was never injected into CI.
bun install
error: GET https://npm.acme.internal/@acme%2fui - 401 Unauthorized
error: Failed to install 1 packageCommon causes
The registry token is missing or not injected
bunfig.toml references $NPM_TOKEN but the secret was never exposed to the step, so Bun sends an anonymous request and gets 401.
The token is valid but lacks read scope
A 403 means the token authenticated but is not permitted to read that scope or package on the registry.
How to fix it
Configure the registry and token in bunfig.toml
- Store the registry token as a repository or organization secret.
- Reference it via an env var in bunfig.toml, not a literal token.
- Export the secret into the step env so Bun can read it.
[install.scopes]
"@acme" = { url = "https://npm.acme.internal/", token = "$NPM_TOKEN" }Inject the secret in the workflow
Expose the token to the install step; a persistent 403 means the token needs read scope, not a retry.
- run: bun install --frozen-lockfile
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}How to prevent it
- Keep registry tokens in CI secrets, referenced via env in bunfig.toml.
- Grant least-privilege read scope to the package feed.
- Never commit a literal token in bunfig.toml.