vxcontrol/pentagi · error
error checking token status: %w
Error message
error checking token status: %w
What it means
In tryProtoTokenAuthentication, after ValidateAPIToken succeeds, p.tokenCache.GetStatus(apiClaims.TokenID) fetches the token's DB status and privileges. Any error other than gorm.ErrRecordNotFound is wrapped as "error checking token status: %w" — the token's database state could not be read, so the request cannot be authorized.
Source
Thrown at backend/pkg/server/auth/auth_middleware.go:227
// skip validation if using default salt (for backward compatibility)
if p.globalSalt == "" || p.globalSalt == "salt" {
return authResultSkip, errors.New("token validation disabled with default salt")
}
// try to validate as API token first (new format with JWT signing key)
apiClaims, apiErr := ValidateAPIToken(token, p.globalSalt)
if apiErr != nil {
return authResultFail, errors.New("token is invalid")
}
// check token status and get privileges through cache
status, privileges, err := p.tokenCache.GetStatus(apiClaims.TokenID)
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return authResultFail, errors.New("token not found in database")
}
return authResultFail, fmt.Errorf("error checking token status: %w", err)
}
if status != models.TokenStatusActive {
return authResultFail, errors.New("token has been revoked")
}
// Verify user hash matches database
dbHash, userStatus, err := p.userCache.GetUserHash(apiClaims.UID)
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return authResultFail, errors.New("user has been deleted")
}
return authResultFail, fmt.Errorf("error checking user status: %w", err)
}
if userStatus == models.UserStatusBlocked {
return authResultFail, errors.New("user has been blocked")
}
View on GitHub (pinned to ea665308ba)
Solutions
- Check the wrapped %w cause in logs and verify PostgreSQL health/connectivity
- Retry the API call if the failure was transient (restart/timeout)
- Apply pending migrations and confirm the api_tokens table exists with expected columns
- Review tokenCache/db connection-pool settings for the request volume
Defensive patterns
Strategy: retry
Validate before calling
// pre-flight: confirm the token exists/active before hammering the API
// (e.g., via the settings endpoint or a DB check)
// if tokenStatus(tokenID) != TokenStatusActive { reissueToken() } Type guard
func isTokenStatusError(err error) bool {
return err != nil && strings.Contains(err.Error(), "error checking token status:") &&
!errors.Is(err, gorm.ErrRecordNotFound)
} Try / catch
resp, err := callAPI()
if err != nil && strings.Contains(err.Error(), "error checking token status") {
time.Sleep(backoff)
return callAPI() // transient DB failure; retry
}
return resp, err Prevention
- Add DB health/readiness checks before serving API traffic
- Size the connection pool for API-token request volume
- Keep migrations current so token queries never hit schema errors
- Distinguish NotFound (revoke/reissue) from infrastructure errors in client retry logic
When it happens
Trigger: Postgres unavailable or timing out while resolving apiClaims.TokenID; connection-pool exhaustion; missing schema/migrations causing the query to fail; cache layer returning a non-NotFound error.
Common situations: DB outage or failover during API traffic; pool exhausted under heavy concurrent API-token usage; incomplete migrations on a fresh deployment.
Related errors
- token not found in database
- token required
- token is invalid
- token has been revoked
- error checking user status: %w
AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01).
Data as JSON: /api/errors/a04abc3092bd1390.
Report an issue: GitHub.