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

  1. Check the wrapped %w cause in logs and verify PostgreSQL health/connectivity
  2. Retry the API call if the failure was transient (restart/timeout)
  3. Apply pending migrations and confirm the api_tokens table exists with expected columns
  4. 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

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


AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01). Data as JSON: /api/errors/a04abc3092bd1390. Report an issue: GitHub.