hcengineering/platform · error · TokenError
Token revocation could not be verified
Error message
Token revocation could not be verified
What it means
For revokable API tokens, isApiTokenRevoked asks the account service whether the token was revoked. If the account service cannot be reached, revocation status is unknown, and the code deliberately refuses the token (fail-closed) rather than letting a possibly-revoked token pass, while still trusting cached verdicts within the TTL.
Source
Thrown at foundations/core/packages/token/src/token.ts:208
}
async function isApiTokenRevoked (apiTokenId: string, token: Token, raw: string, now: number): Promise<boolean> {
const cached = revocationCache.get(apiTokenId)
if (cached !== undefined && now - cached.checkedAt <= REVOCATION_CACHE_TTL_MS) {
return cached.revoked
}
try {
const revoked = await (apiTokenRevocationChecker as ApiTokenRevocationChecker)(apiTokenId, token, raw)
cacheRevocation(apiTokenId, revoked, now)
return revoked
} catch {
// The account is the only authority on revocation. If it cannot be reached we
// do not know whether this token still stands, so refuse it rather than let a
// revoked token survive by making the account unreachable. A verdict from
// within the TTL is still trusted, which keeps brief outages from cutting off
// healthy tokens mid-flight.
throw new TokenError('Token revocation could not be verified')
}
}
/**
* Decodes and fully validates a token: signature (via {@link decodeToken}),
* expiry, and — for revokable API tokens — revocation. Reuse this instead of
* `decodeToken` anywhere expired or revoked tokens must be rejected (transactor
* REST API, blob access, etc.) so the policy lives in one place.
* @public
*/
export async function verifyToken (token: string, secret?: string): Promise<Token> {
const decoded = decodeToken(token, true, secret)
if (isTokenExpired(decoded)) {
throw new TokenError('Token expired')
}
const apiTokenId = decoded.extra?.apiTokenId
if (apiTokenId !== undefined && apiTokenRevocationChecker !== undefined) {
if (await isApiTokenRevoked(apiTokenId, decoded, token, Date.now())) {View on GitHub (pinned to 63e28dc964)
Solutions
- Restore connectivity to the account service and retry verification
- Check the account service health/endpoint configuration
- Increase or rely on the revocation-verdict TTL so brief outages don't break healthy tokens
- As a caller, catch TokenError and surface 'try again shortly' rather than treating it as a bad credential
Example fix
// before
const token = await verifyToken(raw) // throws during account-service blip
// after
try {
const token = await verifyToken(raw)
} catch (e) {
if (e.message === 'Token revocation could not be verified') return retryLater()
throw e
} Defensive patterns
Strategy: try-catch
Validate before calling
// No caller-side check can confirm revocation; precondition is account-service reachability await healthCheck(accountServiceUrl) // fail fast if revocation authority is unreachable
Try / catch
try {
const t = await verifyToken(token)
} catch (e) {
if (e instanceof TokenError && e.message === 'Token revocation could not be verified') {
// fail-closed: treat as temporary unavailability, not bad credentials
return res.status(503).send('auth backend unavailable, retry shortly')
}
throw e
} Prevention
- Return 503 with retry, not 401, when this specific message appears
- Monitor account-service health; alert on rising revocation-check failures
- Keep the revocation-verdict TTL long enough to ride out brief outages
- Include retry/backoff around verifyToken in background consumers
When it happens
Trigger: verifyToken on a token with extra.apiTokenId when the account/revocation service call throws — network outage, DNS failure, timeout, or service crash.
Common situations: Partial outages where auth works but the account service is down; network partitions; misconfigured account service endpoint; brief blips during deploys (mitigated by the TTL cache).
Related errors
- "npm view" returned error code ${npmVersionSpawnResult.statu
- Unable to resolve version ${version} of package ${name}: ${e
- response.statusText
- "npm view" returned error code ${npmVersionSpawnResult.statu
- Failed to fetch config
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/3714f9d8496278f1.
Report an issue: GitHub.