Auth0 Home Blog Docs

Access token is not valid within 30 minutes

Hi all,

I am developing APIs using the access token provided by Auth0. The access token will be checked with the following Python code every request sent to my API :

    unverified_header = jwt.get_unverified_header(access_token)
	if unverified_header.get("kid") is None:
		raise AuthError("Invalid access token.", 401)
	rsa_key = {}
	for key in JWKS_INFO["keys"]:
		if key["kid"] == unverified_header["kid"]:
			rsa_key = {
				"kty": key["kty"],
				"kid": key["kid"],
				"use": key["use"],
				"n": key["n"],
				"e": key["e"]
			raise AuthError("Invalid access token.", 401)
	payload = None
	if rsa_key:
			payload = jwt.decode(
		except jwt.ExpiredSignatureError:
			raise AuthError("Access token is expired. Please re-login.", 440)
		except jwt.JWTClaimsError:
			raise AuthError("Incorrect claims, please check the audience and issuer.", 406)
		except requests.exceptions.HTTPError as e:
			raise AuthError("Unable to query userinfo from the Auth0.", e.response.status_code)
		except jose.exceptions.JWTError as e:
			raise AuthError("Invalid access token.", 401)
		raise AuthError("Unable to find appropriate key.", 400)

And strangely the token will become invalid with ExpiredSignatureError randomly within 30 minutes while in the Auth0 application section, we had set the JWT Expiration to 172800 seconds, which is 2 days. Does anyone encounter the same issue? Why do I get such problem? Is it a bug?

Thank you in advance.

The JWT expiration setting within the client application configuration applies to an ID token issued to the client application itself. In general, if you’re calling an API you will be using an access token like you said.

The access token may also indeed use the JWT format so I agree the above naming can be confusing. For an access token issued for an API you created in the dashboard the lifetime depends on the settings configured in the API configuration itself.

The first thing to check would be to confirm that you’re indeed sending an access token and then check the API settings to see if any of the expiration settings would explain what you’re observing.

1 Like

Sorry I am confused with which API you are talking about and I still have no idea where to check.

So here are “APIs” related to my question.

  • API_Ours : the API we developed in python Flask.
  • API_Auth0 : the REST API endpoints Auth0 provides.
  • API_Dashboard : the API listed in the Auth0 dashboard (which is the configuration in the portal of Auth0 on the left side)

So that my question is :

API_Ours is using API_Auth0 to login with user’s access token provided by API_Auth0. Such access token will be validated in API_Ours with each requests user sent in the header. The access token is valid for some time, let’s say 30 minutes. Then such access token becomes expired/invalid which API_Ours will force user to logout.

I would like to know why such access token provided by API_Auth0 expired/invalidated so quick even if I had set the JWT Expiration to 172800 seconds in the API_Dashboard. Where should I look into?

Lets review form a different angle; what’s the value of this settings.AUTH0_API_AUDIENCE? If the validation code is expecting an access token containing an audience with that value, then you should start by checking the settings of that API.

There’s no such thing as a JWT Expiration field within the settings of an API; (APIs section in the dashboard). There’s only settings Token Expiration (Seconds) and Token Expiration For Browser Flows (Seconds). The only configuration screen that I’m aware that uses the terminology JWT Expiration is the settings of a client application and it applies only to an ID token which would bring us back to my first post.

If you’re not worried about disclosing your tenant name or user identifiers it would be helpful if you can share the payload section of the JWT token being sent to your API.

1 Like


Thanks for the reply and the explanation.

We had done a close review in our code and we had found the issue for disconnection. It’s in one line of our code “response.raise_for_status()” for debug.