NuGet "Unable to load the service index ... 401" Private Feed in CI
The feed answered, but with 401 Unauthorized - NuGet reached the index endpoint and was rejected for lack of valid credentials. This is an auth problem: the runner has no token, an expired token, or the wrong username/password for the private feed. A managed self-healing runner will not fix a bad credential - 401 is deterministic until the token is corrected.
What this error means
Restore fails with "Unable to load the service index ... Response status code 401". It reproduces every run with the same credential - re-running does not help until the token is fixed.
error : Unable to load the service index for source
https://nuget.pkg.github.com/contoso/index.json.
error : Response status code does not indicate success: 401 (Unauthorized).Common causes
No credentials were provided to the runner
The feed requires auth but the runner's nuget.config has no packageSourceCredentials, or the token env var is empty in CI.
The token is expired or wrong
A PAT expired, was rotated, or lacks read scope on the feed, so the feed rejects the request.
How to fix it
Provide a valid token from CI secrets
- Store the feed token as a CI secret and inject it into the environment.
- Reference it from
nuget.configcredentials, never inline plaintext. - Re-run restore once the token is present.
<packageSourceCredentials>
<github>
<add key="Username" value="contoso-ci" />
<add key="ClearTextPassword" value="${{ secrets.NUGET_TOKEN }}" />
</github>
</packageSourceCredentials>Rotate or re-scope the token
- Issue a new PAT with read (and the right package) scope on the feed.
- Update the CI secret with the new value.
- Confirm the token has not hit an org SSO/authorization requirement.
How to prevent it
- Track PAT expiry and rotate before it lapses.
- Grant the token the minimum scope the feed needs (package read).
- Keep credentials in CI secrets, never committed to the repo.