unslothai/unsloth · error · HTTPException
Invalid token payload
Error message
Invalid token payload
What it means
HTTP 401 raised when _decode_subject_without_verification cannot extract a subject from the bearer token: jwt.decode with signature/expiration verification disabled still failed to yield a usable 'sub' claim. That means the token is not a well-formed JWT (or lacks a sub), so it can be neither routed to the API-key path nor to the JWT verification path.
Source
Thrown at studio/backend/auth/authentication.py:277
a reset landing mid-request would bless what it just revoked.
"""
token = credentials.credentials
# --- API key path (sk-unsloth-...) ---
if token.startswith(API_KEY_PREFIX):
verified = validate_api_key_with_credential(token)
if verified is None:
raise HTTPException(
status_code = status.HTTP_401_UNAUTHORIZED,
detail = _invalid_api_key_detail(token),
)
username, secret = verified
return username, credential_generation(secret)
# --- JWT path ---
subject = _decode_subject_without_verification(token)
if subject is None:
raise HTTPException(
status_code = status.HTTP_401_UNAUTHORIZED,
detail = "Invalid token payload",
)
record = get_user_and_secret(subject)
if record is None:
raise HTTPException(
status_code = status.HTTP_401_UNAUTHORIZED,
detail = "Invalid or expired token",
)
_salt, _pwd_hash, jwt_secret, must_change_password = record
try:
payload = jwt.decode(token, jwt_secret, algorithms = [ALGORITHM])
if payload.get("sub") != subject:
raise HTTPException(
status_code = status.HTTP_401_UNAUTHORIZED,
detail = "Invalid token payload",View on GitHub (pinned to 203007d190)
Solutions
- Send a real, complete JWT previously issued by the login endpoint (three dot-separated base64url segments ending in a signature).
- Check the token was not truncated or altered in transit (env var quoting, Docker secrets, CI masking).
- If integrating programmatically, obtain the token from the login flow rather than hand-building one.
Example fix
# before
headers = {"Authorization": "Bearer not-a-jwt"}
# after
resp = requests.post(f"{base}/login", json={...})
headers = {"Authorization": f"Bearer {resp.json()['access_token']}"} Defensive patterns
Strategy: type-guard
Type guard
def looks_like_jwt(token: str) -> bool:
parts = token.split('.')
return len(parts) == 3 and all(parts) Try / catch
try:
client.get('/api/x', headers=bearer(tok))
except HTTPStatusError as e:
if e.response.status_code == 401 and 'Invalid token payload' in e.response.text:
tok = login() # obtain a real JWT Prevention
- Always source tokens from the login endpoint; never hand-build auth headers.
- Validate the three-segment JWT shape client-side before sending.
- Check env/quoting for truncation when tokens move through CI or containers.
When it happens
Trigger: Sending a malformed or truncated JWT string in the Authorization header; sending an opaque session string or random token where a JWT is expected; a JWT whose payload has no 'sub' claim; base64 corruption of the payload segment.
Common situations: Manually crafting auth headers; a proxy or client library mangling the header; using the wrong token type for the API (e.g. a CSRF token or opaque id); copy/paste truncating the token at a newline.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Invalid or expired token
- Invalid or expired API key
- GitHub {endpoint} returned {r.status_code} {r.reason}. Token
- Local (stdio) MCP servers can only be configured from the Un
- Password change required
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/7cc30edfb6683273.
Report an issue: GitHub.