makeplane/plane · error · AuthenticationFailed
Given API token is not valid
Error message
Given API token is not valid
What it means
validate_api_token queries APIToken with conditions: token matches, is_active=True, user__is_active=True, and (expired_at > now OR expired_at is null). If APIToken.DoesNotExist is raised, the DRF AuthenticationFailed is thrown with this message, producing an HTTP 401. This is the standard API-token auth path in apps/api/plane/api/middleware.
Source
Thrown at apps/api/plane/api/middleware/api_authentication.py:38
"""
www_authenticate_realm = "api"
media_type = "application/json"
auth_header_name = "X-Api-Key"
def get_api_token(self, request):
return request.headers.get(self.auth_header_name)
def validate_api_token(self, token):
try:
api_token = APIToken.objects.get(
Q(Q(expired_at__gt=timezone.now()) | Q(expired_at__isnull=True)),
token=token,
is_active=True,
user__is_active=True,
)
except APIToken.DoesNotExist:
raise AuthenticationFailed("Given API token is not valid")
# save api token last used
api_token.last_used = timezone.now()
api_token.save(update_fields=["last_used"])
return (api_token.user, api_token.token)
def authenticate(self, request):
token = self.get_api_token(request=request)
if not token:
return None
# Validate the API token
user, token = self.validate_api_token(token)
return user, token
View on GitHub (pinned to 1c8a60f858)
Solutions
- Regenerate the API token in the workspace settings and update the client.
- Confirm the token's user account is active and not suspended.
- Check the token's expired_at; if set and passed, issue a new token.
- Verify the header name matches auth_header_name (default X-API-Key) and the value has no leading/trailing whitespace.
Example fix
# before curl -H 'X-API-Key: stale-or-revoked' https://api/v1/... # after curl -H 'X-API-Key: <newly generated token>' https://api/v1/...
Defensive patterns
Strategy: try-catch
Validate before calling
# before each call, ensure token is non-empty and recently issued import os assert os.environ['PLANE_API_KEY'].strip(), 'missing API token'
Try / catch
try:
client.get('/work-items/')
except AuthenticationFailed as e:
if str(e) == 'Given API token is not valid':
rotate_token(); retry() Prevention
- Rotate revoked tokens promptly
- Store tokens in env/secret manager, not code
- Strip whitespace from header values
- Confirm the owning user is active
When it happens
Trigger: Request with X-API-Key header set to a token that is wrong, revoked (is_active=False), owned by a deactivated user, or past expired_at with no null expiry.
Common situations: Rotated/revoked token still used by an integration; clock skew between client and server expiring the token early; user deactivated but external script still runs; typo in the header value.
Related errors
- Given API token is not valid
- 5017
- AUTH_USER_MISMATCH
- Authentication unsuccessful
- AUTH_MISSING_CREDENTIALS
AI-assisted analysis of makeplane/plane@1c8a60f858 (2026-08-12).
Data as JSON: /api/errors/9262910955a359e2.
Report an issue: GitHub.