getredash/redash · error · Unauthorized

Invalid JWT token

Error message

Invalid JWT token

What it means

Raised by Redash's JWT request loader when the token in the Authorization header fails verification against the org's JWT settings (issuer, audience, algorithms, public certs URL configured under auth_jwt_auth_*). Any signature, issuer, audience, or key-mismatch makes token_is_valid False and the request is rejected as unauthenticated.

Source

Thrown at redash/authentication/__init__.py:186

    payload = None

    if org_settings["auth_jwt_auth_cookie_name"]:
        jwt_token = request.cookies.get(org_settings["auth_jwt_auth_cookie_name"], None)
    elif org_settings["auth_jwt_auth_header_name"]:
        jwt_token = request.headers.get(org_settings["auth_jwt_auth_header_name"], None)
    else:
        return None

    if jwt_token:
        payload, token_is_valid = jwt_auth.verify_jwt_token(
            jwt_token,
            expected_issuer=org_settings["auth_jwt_auth_issuer"],
            expected_audience=org_settings["auth_jwt_auth_audience"],
            algorithms=org_settings["auth_jwt_auth_algorithms"],
            public_certs_url=org_settings["auth_jwt_auth_public_certs_url"],
        )
        if not token_is_valid:
            raise Unauthorized("Invalid JWT token")

    if not payload:
        return

    if "email" not in payload:
        logger.info("No email field in token, refusing to login")
        return

    try:
        user = models.User.get_by_email_and_org(payload["email"], org)
    except models.NoResultFound:
        user = create_and_login_user(current_org, payload["email"], payload["email"])

    return user


def log_user_logged_in(app, user):
    event = {

View on GitHub (pinned to ca79fe988d)

Solutions

  1. Verify the token's iss and aud claims match auth_jwt_auth_issuer and auth_jwt_auth_audience exactly
  2. Decode the token and confirm its alg is listed in auth_jwt_auth_algorithms
  3. Confirm auth_jwt_auth_public_certs_url serves the current JWKS containing the token header's kid
  4. Obtain a fresh token from your identity provider and retry

Example fix

# before
Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6Im9sZC1rZXki...  # stale key

# after: mint a new token with matching claims
import jwt, requests
token = jwt.encode({"email": "user@example.com", "iss": ISSUER, "aud": AUDIENCE}, key, algorithm="RS256")
requests.get(url, headers={"Authorization": f"Bearer {token}"})
Defensive patterns

Strategy: validation

Validate before calling

import jwt
from jwt import PyJWKClient

token = extract_bearer(header)
try:
    key = PyJWKClient(PUBLIC_CERTS_URL).get_signing_key_from_jwt(token).key
    jwt.decode(token, key, algorithms=ALLOWED_ALGS, audience=EXPECTED_AUD, issuer=EXPECTED_ISS)
except jwt.InvalidTokenError as e:
    refresh_token_before_calling_redash(e)

Type guard

def is_valid_redash_jwt(token: str) -> bool:
    try:
        claims = jwt.decode(token, options={"verify_signature": False})
        return claims.get("iss") == EXPECTED_ISSUER and claims.get("aud") == EXPECTED_AUDIENCE and "email" in claims
    except jwt.DecodeError:
        return False

Try / catch

try:
    resp = redash_api.get('/api/queries')
except Unauthorized:
    token = refresh_idp_token(); retry once with the new token

Prevention

When it happens

Trigger: Calling any Redash API endpoint with Authorization: Bearer <jwt> where the token's iss/aud don't match auth_jwt_auth_issuer/auth_jwt_auth_audience, the alg isn't in auth_jwt_auth_algorithms, or the signing key isn't in the JWKS at auth_jwt_auth_public_certs_url.

Common situations: IdP signing-key rotation without updating the certs URL, issuer/audience mismatch after an IdP migration, expired or wrongly-signed tokens, or enabling JWT auth without configuring org settings.

Related errors


AI-assisted analysis of getredash/redash@ca79fe988d (2026-08-28). Data as JSON: /api/errors/d45b312b3b028a97. Report an issue: GitHub.