{"record":{"id":"dc8fa2d5792c9317","repo":"redis/redis-py","slug":"unexpected-token-schema-following-fields-are-miss","errorCode":null,"errorMessage":"Unexpected token schema. Following fields are missing: {missing_fields}","messagePattern":"Unexpected token schema\\. Following fields are missing: (.+?)","errorType":"validation","errorClass":"InvalidTokenSchemaErr","httpStatus":null,"severity":"error","filePath":"redis/auth/token.py","lineNumber":130,"sourceCode":"        )\n\n    def try_get(self, key: str) -> str:\n        return self._decoded.get(key)\n\n    def get_value(self) -> str:\n        return self._value\n\n    def get_expires_at_ms(self) -> float:\n        return float(self._decoded[\"exp\"] * 1000)\n\n    def get_received_at_ms(self) -> float:\n        return datetime.now(timezone.utc).timestamp() * 1000\n\n    def _validate_token(self):\n        actual_fields = {x for x in self._decoded.keys()}\n\n        if len(self.REQUIRED_FIELDS - actual_fields) != 0:\n            raise InvalidTokenSchemaErr(self.REQUIRED_FIELDS - actual_fields)\n","sourceCodeStart":112,"sourceCodeEnd":131,"githubUrl":"https://github.com/redis/redis-py/blob/6a6b581b48225afa0b76912d1028c6035baee932/redis/auth/token.py#L112-L131","documentation":"Raised as InvalidTokenSchemaErr inside JWToken._validate_token when the decoded JWT is missing one or more required fields. JWToken.REQUIRED_FIELDS is {'exp'}, so at minimum the token must contain an 'exp' (expiration) claim. The error message lists exactly which fields are missing. This guards against malformed or non-standard tokens before the token manager tries to compute TTL/renewal.","triggerScenarios":"Constructing JWToken with a token string whose decoded payload lacks the 'exp' claim (or any future field added to REQUIRED_FIELDS). Triggered during token_manager initialization or renewal when it wraps the acquired token in a JWToken.","commonSituations":"The identity provider issued a token without an expiration claim. The token was truncated or corrupted. A custom/legacy token format that omits 'exp'. Clock/encoding issues producing a payload PyJWT decoded but with unexpected keys.","solutions":["Inspect the token payload (jwt.decode without verification) and confirm it contains 'exp'.","Have the identity provider include the 'exp' claim in issued tokens.","If using a token format without 'exp', use a different Token implementation rather than JWToken.","Re-acquire a fresh, complete token from the issuer."],"exampleFix":"# before: token lacks 'exp'\ntoken = JWToken(\"eyJ...payload_without_exp...\")  # InvalidTokenSchemaErr\n# after: issuer includes exp\ntoken = JWToken(\"eyJ...payload_with_exp...\")","handlingStrategy":"validation","validationCode":"import jwt\npayload = jwt.decode(value, options={\"verify_signature\": False})\nif \"exp\" not in payload:\n    raise ValueError(\"token missing required 'exp' claim\")","typeGuard":"def has_required_claims(value: str, required={\"exp\"}) -> bool:\n    import jwt\n    payload = jwt.decode(value, options={\"verify_signature\": False})\n    return required.issubset(payload.keys())","tryCatchPattern":"from redis.auth.err import InvalidTokenSchemaErr\ntry:\n    token = JWToken(value)\nexcept InvalidTokenSchemaErr as e:\n    logger.error(\"rejecting malformed token: %s\", e)\n    raise","preventionTips":["Validate IdP-issued tokens contain 'exp' before use.","Log and reject tokens that fail schema validation rather than retrying blindly."],"tags":["auth","jwt","validation","token"],"backgroundTag":null,"analyzedSha":"6a6b581b48225afa0b76912d1028c6035baee932","analyzedAt":"2026-08-10T12:52:44.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}