When a client application includes a JSON Web Token (JWT) in a request to an
API, the Extensible Service Proxy (ESP)
validates the JWT before sending the request to the API
backend. This page provides troubleshooting information if the JWT validation
fails and ESP returns an error in the response to the client. See
RFC 7519 for more information
about JWTs.
Error: 401: Jwt issuer is not configured
This may happen when deploying ESPv2 in Cloud Run, the flag
--allow-unauthenticated is not used in gcloud run deploy command.
If the flag is not used, the JWT token is intercepted
and verified by Cloud Run access
control IAM server and not by ESPv2. IAM may use a different issuer than
ESPv2.
Error: BAD_FORMAT
Check the
following:
Make sure the JWT contains valid JSON.
Check that the JWT header has the "alg" field and is set to one of the
following: "RS256", "HS256", "RS384",
"HS384", "RS512", or "HS512"
Check the data type of the following fields (if they are present) in the
JWT payload:
The "iat" (issued at), "exp" (expiration time), and
"nbf"(not before) claims are numbers greater than 0 and not
strings.
The "sub" (subject), "iss" (issuer), and
"jti" (JWT ID) fields
are strings.
The "aud" (audience) claim is either a string or an array of
strings.
Ensure that the following claims are present in the JWT payload:
"sub" (subject), "iss" (issuer), and
"aud" (audience).
The following is an example of a decoded JWT token that is valid:
The "exp" (expiration time) claim value is a date and time in the
future. The current date and time must be before the expiration date and time listed
in the "exp" claim.
The "nbf" (not before) claim (If present) is a date and time in the
past. The current date and time must be after or equal to the date and time listed in
the "nbf" claim.
If the "iss" (issuer) claim is an email address, then the "sub" (subject)
and "iss" claims should be the same.
This is to ensure that for e-mail issuers, the JWT is self issued.
Error: KEY_RETRIEVAL_ERROR
Check that the public key URI specified in the
jwks_uri
field in the authentication: providers section of your gRPC .yaml
configuration file is correct and valid.
Error: Issuer not allowed
Check that the "iss" (issuer) claim in your JWT token matches the
issuer
field in the authentication: providers section of your gRPC .yaml
configuration file.
Error: Audience not allowed
If the "aud" (audience) claim in a JWT token matches the Endpoints
service name, then the ESP validates the audience
and ignores the audiences values in your gRPC .yaml configuration file. For
example, if your service name is
"myservice.endpoints.example-project-12345.cloud.goog",
then a JWT with "aud" set to
"myservice.endpoints.example-project-12345.cloud.goog"
or "https://myservice.endpoints.example-project-12345.cloud.goog" is a valid
audience.
If the "aud" claim isn't the same as the Endpoints service
name:
Check that the "aud" claim in the JWT matches one of the audiences
values specified in the authentication: providers section of your gRPC
.yaml configuration file.
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Hard to understand","hardToUnderstand","thumb-down"],["Incorrect information or sample code","incorrectInformationOrSampleCode","thumb-down"],["Missing the information/samples I need","missingTheInformationSamplesINeed","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2025-09-04 UTC."],[[["\u003cp\u003eThe Extensible Service Proxy (ESP) validates JSON Web Tokens (JWTs) before forwarding requests to the API backend, and this page offers troubleshooting for JWT validation failures.\u003c/p\u003e\n"],["\u003cp\u003eThe \u003ccode\u003eBAD_FORMAT\u003c/code\u003e error indicates potential issues with the JWT's structure, such as invalid JSON, incorrect \u003ccode\u003e"alg"\u003c/code\u003e field values, or incorrect data types for fields like \u003ccode\u003e"iat"\u003c/code\u003e, \u003ccode\u003e"exp"\u003c/code\u003e, \u003ccode\u003e"nbf"\u003c/code\u003e, \u003ccode\u003e"sub"\u003c/code\u003e, \u003ccode\u003e"iss"\u003c/code\u003e, \u003ccode\u003e"jti"\u003c/code\u003e, and \u003ccode\u003e"aud"\u003c/code\u003e.\u003c/p\u003e\n"],["\u003cp\u003eThe \u003ccode\u003eTIME_CONSTRAINT_FAILURE\u003c/code\u003e error means that either the \u003ccode\u003e"exp"\u003c/code\u003e (expiration time) claim is missing or invalid, or the \u003ccode\u003e"nbf"\u003c/code\u003e (not before) claim, if present, indicates that the token is not yet valid.\u003c/p\u003e\n"],["\u003cp\u003eThe \u003ccode\u003eKEY_RETRIEVAL_ERROR\u003c/code\u003e error suggests a problem with the \u003ccode\u003ejwks_uri\u003c/code\u003e specified in the gRPC configuration, which should be checked for accuracy.\u003c/p\u003e\n"],["\u003cp\u003eThe \u003ccode\u003eAudience not allowed\u003c/code\u003e error occurs when the \u003ccode\u003e"aud"\u003c/code\u003e claim in the JWT does not match either the Endpoints service name or the \u003ccode\u003eaudiences\u003c/code\u003e values specified in the gRPC configuration.\u003c/p\u003e\n"]]],[],null,["# Troubleshooting JWT validation\n\n[OpenAPI](/endpoints/docs/openapi/troubleshoot-jwt \"View this page for the Cloud Endpoints OpenAPI docs\") \\| gRPC\n\n\u003cbr /\u003e\n\nWhen a client application includes a JSON Web Token (JWT) in a request to an\nAPI, the [Extensible Service Proxy (ESP)](/endpoints/docs/openapi/glossary#extensible_service_proxy)\nvalidates the JWT before sending the request to the API\nbackend. This page provides troubleshooting information if the JWT validation\nfails and ESP returns an error in the response to the client. See\n[RFC 7519](https://tools.ietf.org/html/rfc7519) for more information\nabout JWTs.\n**Error: `401: Jwt issuer is not configured`**\n\nThis may happen when deploying ESPv2 in Cloud Run, the flag\n`--allow-unauthenticated` is not used in `gcloud run deploy` command.\nIf the flag is not used, the JWT token is intercepted\nand verified by Cloud Run access control IAM server and not by ESPv2. IAM may use a different issuer than ESPv2.\n**Error: `BAD_FORMAT`**\n\nCheck the\nfollowing:\n\n- Make sure the JWT contains valid JSON.\n- Check that the JWT header has the `\"alg\"` field and is set to one of the following: `\"RS256\"`, `\"HS256\"`, `\"RS384\"`, `\"HS384\"`, `\"RS512\"`, or `\"HS512\"`\n- Check the data type of the following fields (if they are present) in the JWT payload:\n - The `\"iat\"` (issued at), `\"exp\"` (expiration time), and `\"nbf\"`(not before) claims are numbers greater than 0 and not strings.\n - The `\"sub\"` (subject), `\"iss\"` (issuer), and `\"jti\"` (JWT ID) fields are strings.\n - The `\"aud\"` (audience) claim is either a string or an array of strings.\n- Ensure that the following claims are present in the JWT payload: `\"sub\"` (subject), `\"iss\"` (issuer), and `\"aud\"` (audience).\n\nThe following is an example of a decoded JWT token that is valid: \n\n```\n{\n \"alg\": \"RS256\",\n \"typ\": \"JWT\",\n \"kid\": \"42ba1e234ac91ffca687a5b5b3d0ca2d7ce0fc0a\"\n}\n\nPayload:\n{\n \"iss\": \"myservice@myproject.iam.gserviceaccount.com\",\n \"iat\": 1493833746,\n \"aud\": \"myservice.appspot.com\",\n \"exp\": 1493837346,\n \"sub\": \"myservice@myproject.iam.gserviceaccount.com\"\n}\n```\n**Error: `TIME_CONSTRAINT_FAILURE`**\n\nUse [jwt.io](https://jwt.io/) to decode the JWT and make sure that:\n\n- The `\"exp\"` (expiration time) claim exists.\n- The `\"exp\"` (expiration time) claim value is a date and time in the future. The current date and time must be before the expiration date and time listed in the `\"exp\"` claim.\n- The `\"nbf\"` (not before) claim (If present) is a date and time in the past. The current date and time must be after or equal to the date and time listed in the `\"nbf\"` claim.\n\n**Error: `UNKNOWN`**\n\nUse [jwt.io](https://jwt.io/) to decode the JWT and ensure that:\n\n- If the `\"iss\"` (issuer) claim is an email address, then the `\"sub\"` (subject) and `\"iss\"` claims should be the same. This is to ensure that for e-mail issuers, the JWT is self issued.\n\n**Error: `KEY_RETRIEVAL_ERROR`**\n\n- Check that the public key URI specified in the [`jwks_uri`](/endpoints/docs/grpc/service-account-authentication#set_up_authentication_in_the_grpc_api_configuration) field in the `authentication: providers` section of your gRPC `.yaml` configuration file is correct and valid.\n\n**Error: `Issuer not allowed`**\n\n- Check that the `\"iss\"` (issuer) claim in your JWT token matches the [`issuer`](/endpoints/docs/grpc/service-account-authentication#set_up_authentication_in_the_grpc_api_configuration) field in the `authentication: providers` section of your gRPC `.yaml` configuration file.\n\n**Error: `Audience not allowed`**\n\nIf the `\"aud\"` (audience) claim in a JWT token matches the Endpoints\nservice name, then the ESP validates the audience\nand ignores the `audiences` values in your gRPC `.yaml` configuration file. For\nexample, if your service name is\n`\"myservice.endpoints.example-project-12345.cloud.goog\"`,\nthen a JWT with `\"aud\"` set to\n`\"myservice.endpoints.example-project-12345.cloud.goog\"`\nor `\"https://myservice.endpoints.example-project-12345.cloud.goog\"` is a valid\naudience.\n\nIf the `\"aud\"` claim isn't the same as the Endpoints service\nname:\n\n- Check that the `\"aud\"` claim in the JWT matches one of the `audiences` values specified in the `authentication: providers` section of your gRPC `.yaml` configuration file."]]