Package Registry Auth Failures
A build fails. The log says the package does not exist. It exists.
npm error code E401npm error 401 Unauthorized - GET https://npm.pkg.github.com/download/@arda-cards/design-system/7.2.0/... - unauthenticatedThat message is unusually honest. Most of the time this failure arrives wearing the wrong name — a Gradle plugin “not found in any of the following sources”, an npm package that “could not be resolved”, a Maven artifact missing from a repository it is plainly published to. The registry refuses an unauthenticated read and the resolver reports the only thing it can distinguish: nothing came back.
When any Arda build or deploy step reports an internally published package as missing, check the credential before you check the release.
Two witnesses, two ecosystems
Section titled “Two witnesses, two ecosystems”Both were diagnosed the same night, in different repositories and different package managers.
Gradle plugin resolution on common-module. A plugin resolved from GitHub Packages failed as unavailable. The credential was the cause.
npm package resolution on arda-frontend-app. An Amplify preview build failed fetching @arda-cards/design-system from npm.pkg.github.com. The Amplify app’s configured registry read credential is invalid, expired, or scoped too narrowly — which of the three was never established, and this page does not guess. Establishing it means inspecting the credential, which is a change to a live AWS application and needs the operator’s word.
Two ecosystems is what makes this a regime rather than one resolver’s quirk. A third would not add much; one would not have been enough.
What was checked first, and was wrong
Section titled “What was checked first, and was wrong”The Amplify failure was first attributed to the app’s 50-branch preview quota.
That was refuted, not merely left unconfirmed, and both observations matter: the app sat at 37 of 50 branches, and the preview branch for the failing pull request was created and its build actually ran. Quota exhaustion prevents branch creation outright, so either observation alone rules it out.
This is recorded because the next person will reach for the quota too. It is the visible, countable, plausible cause, and it is in the same subsystem. Knowing it was checked and eliminated is worth more than knowing the answer.
The order to check in
Section titled “The order to check in”- Read the actual error body, not the summary line. The resolver’s headline says “not found”; the underlying HTTP status is in the log. A
401or403settles it immediately. - Confirm the artifact is published at the exact version requested. Cheap, and it eliminates the case where the message is telling the truth.
- Check the credential the failing step uses — not the one you use locally. A build agent, an Amplify app and a developer laptop each carry their own, and they expire independently.
- Only then look for a missing release.
Steps one and three are where the answer almost always is, and step one costs nothing.
The related trap: a credential that was never there
Section titled “The related trap: a credential that was never there”A build can lose its credential without anything expiring. Giving a Gradle build its own GRADLE_USER_HOME — the fix for daemons shared across worktrees — creates a home with no gradle.properties, so the registry credentials simply are not present. The failure is identical to an expired token, and identical to a missing package.
Anything that isolates a build’s configuration has to seed the credentials into it. See Worktree Conventions for that mechanism.
Sources
Section titled “Sources”Diagnosed on arda-frontend-app’s Amplify preview builds and common-module’s Gradle plugin resolution, 2026-09-09. The submission is /workbooks/notebooks/domain-ontology/streams/harry-tuttle/submission-c8-amplify-npm-gpr-401.md.
Copyright: © Arda Systems 2025-2026, All rights reserved