HumanSignal/label-studio · error · AuthenticationFailed
Authentication token no longer valid: legacy token…
Error message
Authentication token no longer valid: legacy token authentication has been disabled for this organization
What it means
REST-framework AuthenticationFailed raised during legacy (non-JWT) API token authentication when the user's organization has disabled legacy API tokens. The user exists and the token matches, but the org policy makes the token no longer acceptable.
Solutions
- Generate a new JWT-based API token via the LSAPIToken endpoint (POST /api/auth/token or /api/sts/tokens)
- Update scripts/clients to send the new token
- If legacy tokens must keep working, have the organization admin re-enable legacy API tokens for the org
- Ask the user to log out/in and re-issue credentials
Example fix
// before curl -H 'Authorization: Token <legacy-token>' http://localhost:8080/api/projects/ // after curl -H 'Authorization: Token <new-jwt-api-token>' http://localhost:8080/api/projects/
Defensive patterns
Strategy: try-catch
Validate before calling
const res = await fetch('/api/current-user/whoami', {headers:{Authorization:`Token ${tok}`}});
if (res.status === 401 && (await res.text()).includes('legacy token')) {
await migrateToJwtToken();
} Try / catch
try:
resp = requests.get(url, headers={'Authorization': f'Token {legacy_token}'})
resp.raise_for_status()
except requests.HTTPError as e:
if e.response.status_code == 401:
new_token = create_ls_api_token()
headers['Authorization'] = f'Token {new_token}'
resp = requests.get(url, headers=headers) Prevention
- Migrate to JWT LSAPITokens organization-wide
- Centralize token issuance/refresh in one client helper
- Re-issue tokens whenever org auth policy changes
- Alert on 401s mentioning legacy tokens
When it happens
Trigger: Any authenticated API request (via authenticate/__call__ of the auth class) using an old-style API token while org.jwt.legacy_api_tokens_enabled is False; also surfaced through serializer clean().
Common situations: Organization upgraded to JWT-based LSAPIToken auth and an admin toggled legacy tokens off; scripts/integrations still storing the old API token; users copied old tokens from browser settings after migration.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Invalid Label Studio token
- token_exists
- PermissionDenied
- choices(values:list, weights:list) requires one or two…
- detail
AI-assisted analysis of HumanSignal/label-studio@0b49e9b539 (2026-08-29).
Data as JSON: /api/errors/a73088310ec375f0.
Report an issue: GitHub.
Appendix: source
Thrown at label_studio/jwt_auth/auth.py:35
from core.current_request import CurrentContext
from core.feature_flags import flag_set
auth_result = super().authenticate(request)
# Update CurrentContext with authenticated user
if auth_result is not None:
user, _ = auth_result
CurrentContext.set_user(user)
JWT_ACCESS_TOKEN_ENABLED = flag_set('fflag__feature_develop__prompts__dia_1829_jwt_token_auth')
if JWT_ACCESS_TOKEN_ENABLED and (auth_result is not None):
user, _ = auth_result
org = user.active_organization
org_id = org.id if org else None
# raise 401 if legacy API token auth disabled (i.e. this token is no longer valid)
if org and (not org.jwt.legacy_api_tokens_enabled):
raise AuthenticationFailed(
'Authentication token no longer valid: legacy token authentication has been disabled for this organization'
)
logger.info(
'Legacy token authentication used',
extra={'user_id': user.id, 'organization_id': org_id, 'endpoint': request.path},
)
return auth_result
class JWTAuthScheme(OpenApiAuthenticationExtension):
target_class = 'jwt_auth.auth.TokenAuthenticationPhaseout'
name = 'Token'
def get_security_definition(self, auto_schema):
return {
'type': 'apiKey',
'name': 'Authorization',View on GitHub (pinned to 0b49e9b539)