pnpm/pnpm · error · PnpmError
REGISTRY_ERROR
REGISTRY_ERROR
Error message
Failed to ${action} package: ${response.status} ${response.statusText}. ${errorBody} What it means
The catch-all of the access command's `throwRegistryError` helper: the registry answered with a status other than 401/403/404/422, so the CLI cannot map it to a specific cause and reports the raw status, statusText, and sanitized body. In practice this is 5xx server errors, gateway timeouts, and nonstandard codes returned by proxies or private registries.
Source
Thrown at pnpm11/registry-access/commands/src/access.ts:570
}
return parsed.escapedName ?? encodeURIComponent(packageName).replace(/^%40/, '@')
}
async function throwRegistryError (response: Response, action: string): Promise<never> {
const errorBody = sanitize(await readErrorBody(response))
if (response.status === 401) {
throw new PnpmError('UNAUTHORIZED', `You must be logged in to ${action} packages. ${errorBody}`)
}
if (response.status === 403) {
throw new PnpmError('FORBIDDEN', `You do not have permission to ${action} this package. ${errorBody}`)
}
if (response.status === 404) {
throw new PnpmError('PACKAGE_NOT_FOUND', `Package not found in registry. ${errorBody}`)
}
if (response.status === 422) {
throw new PnpmError('ACCESS_VALIDATION_ERROR', `Invalid request: ${errorBody}`)
}
throw new PnpmError('REGISTRY_ERROR', `Failed to ${action} package: ${response.status} ${response.statusText}. ${errorBody}`)
}
function sanitize (text: string): string {
let result = ''
for (let i = 0; i < text.length; i++) {
const code = text.charCodeAt(i)
if ((code > 31 && code !== 127) || code === 9 || code === 10) {
result += text[i]
}
}
return result
}
View on GitHub (pinned to 6261b7f388)
Solutions
- Retry the command after a short wait — most 5xx responses are transient.
- Check the registry's status page (status.npmjs.org for npmjs.org) if failures persist.
- If behind a corporate proxy, verify the proxy permits the HTTP methods (PUT/DELETE) the access commands use.
- Test basic connectivity to the same registry: `pnpm ping --registry <url>`.
Example fix
# before pnpm access set status=public @scope/pkg # ERR_PNPM_REGISTRY_ERROR Failed to set status for package: 503 Service Unavailable # after # wait for the registry incident to clear, verify, then retry pnpm ping && pnpm access set status=public @scope/pkg
Defensive patterns
Strategy: retry
Validate before calling
// pre-flight: confirm the registry is reachable before a mutation
import { execSync } from 'child_process'
function assertRegistryReachable (registry = 'https://registry.npmjs.org/'): void {
execSync(`pnpm ping --registry ${registry}`, { stdio: 'pipe' })
} Try / catch
async function withRegistryRetry (fn: () => Promise<string>, attempts = 3): Promise<string> {
for (let i = 0; i < attempts; i++) {
try {
return await fn()
} catch (err) {
const code = 'code' in err ? (err as { code: string }).code : ''
const msg = err instanceof Error ? err.message : ''
const transient = code === 'REGISTRY_ERROR' && /\b(5\d\d|429)\b/.test(msg)
if (!transient || i === attempts - 1) throw err
await new Promise((r) => setTimeout(r, 2 ** i * 1000))
}
}
throw new Error('unreachable')
} Prevention
- Retry access mutations with exponential backoff — they are idempotent settings (visibility, MFA, grants).
- Check status.npmjs.org before blaming your config when many commands fail at once.
- Ensure corporate proxies allow the PUT/DELETE methods these endpoints use.
- Alert on repeated 5xx from the same registry to catch proxy misconfiguration early.
When it happens
Trigger: Any access subcommand whose HTTP request returns e.g. 500, 502, 503 from registry.npmjs.org during an incident, or from a corporate proxy/Artifactory in front of the registry; rare 409s or custom codes from non-npm registries.
Common situations: npm registry outage or degraded performance (check status.npmjs.org); a corporate proxy returning 502 for PUT/DELETE verbs; private registries that implement the access endpoints partially and return 500 for unsupported operations.
Related errors
- REGISTRY_ERROR
- ACCESS_SET_MFA_PACKAGE_REQUIRED
- ACCESS_GRANT_ARGS_REQUIRED
- ACCESS_GRANT_PACKAGE_REQUIRED
- ACCESS_REVOKE_ARGS_REQUIRED
AI-assisted analysis of pnpm/pnpm@6261b7f388 (2026-08-17).
Data as JSON: /api/errors/64096ea914556eff.
Report an issue: GitHub.