{"record":{"id":"d45b312b3b028a97","repo":"getredash/redash","slug":"invalid-jwt-token","errorCode":null,"errorMessage":"Invalid JWT token","messagePattern":"Invalid JWT token","errorType":"http","errorClass":"Unauthorized","httpStatus":401,"severity":"error","filePath":"redash/authentication/__init__.py","lineNumber":186,"sourceCode":"    payload = None\n\n    if org_settings[\"auth_jwt_auth_cookie_name\"]:\n        jwt_token = request.cookies.get(org_settings[\"auth_jwt_auth_cookie_name\"], None)\n    elif org_settings[\"auth_jwt_auth_header_name\"]:\n        jwt_token = request.headers.get(org_settings[\"auth_jwt_auth_header_name\"], None)\n    else:\n        return None\n\n    if jwt_token:\n        payload, token_is_valid = jwt_auth.verify_jwt_token(\n            jwt_token,\n            expected_issuer=org_settings[\"auth_jwt_auth_issuer\"],\n            expected_audience=org_settings[\"auth_jwt_auth_audience\"],\n            algorithms=org_settings[\"auth_jwt_auth_algorithms\"],\n            public_certs_url=org_settings[\"auth_jwt_auth_public_certs_url\"],\n        )\n        if not token_is_valid:\n            raise Unauthorized(\"Invalid JWT token\")\n\n    if not payload:\n        return\n\n    if \"email\" not in payload:\n        logger.info(\"No email field in token, refusing to login\")\n        return\n\n    try:\n        user = models.User.get_by_email_and_org(payload[\"email\"], org)\n    except models.NoResultFound:\n        user = create_and_login_user(current_org, payload[\"email\"], payload[\"email\"])\n\n    return user\n\n\ndef log_user_logged_in(app, user):\n    event = {","sourceCodeStart":168,"sourceCodeEnd":204,"githubUrl":"https://github.com/getredash/redash/blob/ca79fe988d81cdac9675b412f3dfcab107bc1fbc/redash/authentication/__init__.py#L168-L204","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Verify the token's iss and aud claims match auth_jwt_auth_issuer and auth_jwt_auth_audience exactly","Decode the token and confirm its alg is listed in auth_jwt_auth_algorithms","Confirm auth_jwt_auth_public_certs_url serves the current JWKS containing the token header's kid","Obtain a fresh token from your identity provider and retry"],"exampleFix":"# before\nAuthorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6Im9sZC1rZXki...  # stale key\n\n# after: mint a new token with matching claims\nimport jwt, requests\ntoken = jwt.encode({\"email\": \"user@example.com\", \"iss\": ISSUER, \"aud\": AUDIENCE}, key, algorithm=\"RS256\")\nrequests.get(url, headers={\"Authorization\": f\"Bearer {token}\"})","handlingStrategy":"validation","validationCode":"import jwt\nfrom jwt import PyJWKClient\n\ntoken = extract_bearer(header)\ntry:\n    key = PyJWKClient(PUBLIC_CERTS_URL).get_signing_key_from_jwt(token).key\n    jwt.decode(token, key, algorithms=ALLOWED_ALGS, audience=EXPECTED_AUD, issuer=EXPECTED_ISS)\nexcept jwt.InvalidTokenError as e:\n    refresh_token_before_calling_redash(e)","typeGuard":"def is_valid_redash_jwt(token: str) -> bool:\n    try:\n        claims = jwt.decode(token, options={\"verify_signature\": False})\n        return claims.get(\"iss\") == EXPECTED_ISSUER and claims.get(\"aud\") == EXPECTED_AUDIENCE and \"email\" in claims\n    except jwt.DecodeError:\n        return False","tryCatchPattern":"try:\n    resp = redash_api.get('/api/queries')\nexcept Unauthorized:\n    token = refresh_idp_token(); retry once with the new token","preventionTips":["Automate token refresh before expiry in API clients","Keep auth_jwt_auth_issuer/audience/algorithms in sync with IdP metadata","Monitor IdP signing-key rotations and update the certs URL promptly"],"tags":["redash","jwt","authentication","auth-header"],"backgroundTag":"jwt-validation-failed","analyzedSha":"ca79fe988d81cdac9675b412f3dfcab107bc1fbc","analyzedAt":"2026-08-28T18:32:34.637Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}