Principal Not Eligible
URI: https://docs.ankatech.co/errors/principal-not-eligible
HTTP Status: 403 Forbidden
When you see this
A signed-in user's session asked for a new access token with its refresh token (POST /api/v3/auth/token, grant_type=refresh_token), and the platform, re-checking that user before issuing the token, found that the user is no longer eligible for a token in that tenant.
This problem type is the platform's internal answer to that check. The client that sent the refresh never receives it: the token endpoint turns it into the OAuth 2.0 error invalid_grant (400, "Refresh token is no longer valid. Please re-authenticate."), as RFC 6749 §5.2 prescribes for a grant that can no longer be honoured. An operator investigating that invalid_grant finds it in the auth-api log as REFRESH_TOKEN GRANT DENIED: principal no longer eligible, with the principal and tenant identifiers.
Five conditions produce it, and the response is byte-identical for all of them:
- the tenant does not exist;
- the tenant's lifecycle state does not permit login (for example, it is suspended or closed);
- the user does not exist;
- the user belongs to a different tenant;
- the user is not
ACTIVE.
The document deliberately does not say which one applied. Telling them apart would reveal which users exist and which tenant each belongs to. The service records the specific cause in its own log.
This is not Forbidden: nothing about the requesting service's authority is being refused. What is refused is the user. The sibling refusal of the same check, Unsupported Principal Type, answers a principal type other than HUMAN.
Common Causes
- A user was suspended, disabled or deleted after their last login, and their session attempted a refresh.
- The user's tenant was suspended or closed.
- A refresh token issued in one tenant was presented with another tenant's identifier.
Response Example
{
"type": "https://docs.ankatech.co/errors/principal-not-eligible",
"title": "Principal Not Eligible",
"status": 403,
"detail": "The principal is not eligible for role resolution in the specified tenant.",
"timestamp": 1730000000,
"extensions": {
"requestId": "550e8400-e29b-41d4-a716-446655440000"
}
}
Content-Type: application/problem+json — the response follows RFC 9457 Problem Details. Its instance member names the platform's internal request, which is not part of the published API, and is omitted here.
How to Resolve
- As a client, treat the
invalid_granton refresh as the end of the session and send the user back to sign in; do not retry the refresh. - As an operator investigating a user who cannot stay signed in, check the user's status and the tenant's lifecycle state in the admin console, and search the admin-api log for the
requestIdto see which of the five conditions applied.
For full schema definitions, examples, and interactive testing, see the Developer Hub Reference.