redis/redis-py · error · TokenRenewalErr
Requested token is expired
Error message
Requested token is expired
What it means
Raised as TokenRenewalErr from the sync _renew_token (redis/auth/token_manager.py:284) after acquire_token(force_refresh=True) returns a token whose is_expired() is True. The identity provider handed back a token that is already past its expiry, so renewal produced nothing usable. If an on_error listener is registered the error is routed there, otherwise it is re-raised.
Source
Thrown at redis/auth/token_manager.py:284
- refresh_before
- (datetime.now(timezone.utc).timestamp() * 1000)
)
def _renew_token(self, skip_initial: bool = False):
"""
Task to renew token from identity provider.
Schedules renewal tasks based on token TTL.
"""
try:
token_res = self.acquire_token(force_refresh=True)
delay = self._calculate_renewal_delay(
token_res.get_token().get_expires_at_ms(),
token_res.get_token().get_received_at_ms(),
)
if token_res.get_token().is_expired():
raise TokenRenewalErr("Requested token is expired")
if self._listener.on_next is None:
logger.warning(
"No registered callback for token renewal task. Renewal cancelled"
)
return
if not skip_initial:
try:
self._listener.on_next(token_res.get_token())
except Exception as e:
raise TokenRenewalErr(e)
if delay <= 0:
return
loop = asyncio.get_running_loop()
self._next_timer = loop.call_later(delay, self._renew_token)View on GitHub (pinned to da03cdc7e8)
Solutions
- Check for clock skew between the client and the identity provider; synchronize NTP.
- Inspect the token's exp vs current time to confirm the IdP is issuing valid-lifetime tokens.
- Register an on_error listener to handle renewal failures gracefully and trigger re-auth.
- Retry renewal once after a short delay in case the issue is transient.
Example fix
# before
# token_manager renews and IdP returns already-expired token -> TokenRenewalErr
# after
# register an on_error handler and verify IdP exp / clock sync
listener.on_error = lambda e: logging.error('renewal failed: %s', e) Defensive patterns
Strategy: try-catch
Validate before calling
import time
token_exp = decoded_jwt.get('exp')
if token_exp is not None and token_exp * 1000 <= time.time() * 1000:
logger.warning('IdP returned an already-expired token') Type guard
def token_already_expired(token) -> bool:
return token.is_expired() Try / catch
from redis.auth.err import TokenRenewalErr
try:
token_manager._renew_token()
except TokenRenewalErr as e:
logger.error('sync renewal returned expired token: %s', e)
reauthenticate() Prevention
- Sync clocks via NTP on all hosts running token renewal.
- Register an on_error listener to capture renewal failures.
When it happens
Trigger: A scheduled/sync token renewal where the IdP's response token's exp is already in the past; significant clock skew between client and IdP; IdP misconfiguration issuing instantly-expiring tokens.
Common situations: Clock skew (client clock ahead of IdP); IdP bug returning expired tokens; long network delay between token issue and receipt; wrong exp units in the IdP response.
Related errors
- {e}
- Redis Cluster cannot be connected. Please provide at least o
- 'username' and 'password' cannot be passed along with 'crede
- Invalid Username or Password
- The PyJWT library is required for {self.__class__.__name__}.
AI-assisted analysis of redis/redis-py@da03cdc7e8 (2026-08-04).
Data as JSON: /data/errors/025f42546a7b61e1.json.
Report an issue: GitHub.