401 Unauthorized from GitLab API after personal access token expiry: distinguishing expiry from scope or revocation failures
0 reputation · 01 Oct 2025, 17:42 UTC
Goal
I want a reliable way to detect that a GitLab personal access token has expired, as opposed to being revoked, mis-scoped, or rejected for another reason, so that an automation job can trigger rotation instead of failing silently. Assume a recent GitLab version (16.x) where PATs require an expiration date and administrators can cap token lifetime.
Constraints and uncertainty
From what I understand, GitLab returns a generic 401 Unauthorized for expired tokens, the same status used for invalid or revoked tokens, and not every client surfaces a distinct "token expired" signal. That makes root-cause diagnosis ambiguous when a pipeline or integration suddenly starts failing. I am also unsure whether the response body or headers differ between expiry and other auth failures, and whether behavior is consistent between the REST API and Git-over-HTTP.
Questions
Does GitLab's API response to an expired PAT contain any indicator (error message, header, or audit event) that distinguishes expiry from revocation or a bad token?
Is there a supported way to query a token's expiry state proactively (for example via the /personal_access_tokens self endpoint) so rotation can happen before jobs start failing?
Does this behavior differ between user PATs and project/group access tokens in current versions?