Documentation

API Troubleshooting for Consumers in the DHCS Developer Portal

Overview

This document offers troubleshooting tips for common errors you may encounter while using DHCS APIs. If you have questions or face issues not addressed in the documentation, please submit a support request through the portal (see Support below).

I just received an http 429 (too many requests), what just happened?

Most common cause

You may have exceeded the allowed number of API requests in a given time period. If this is the case, the API gateway is rate limiting your requests.

Context

By default, the Gloo gateway limits requests to 100 per second. However, this rate limit is self-service configurable, so it may have been configured to be less than that. For instance, if the infrastructure checks an API's health endpoint once a minute, it can be configured to allow only 5 requests per minute. This adjustment effectively manages traffic from other sources. If the health endpoint receives 6 requests in a minute, it will likely respond with a 429 status code, indicating that the request limit has been exceeded.

Example

A recent real rate limited 429 example looked like this (notice the x-envoy-ratelimited: true):

curl -I -X 'GET' \
  'https://example-api.gateway.mes.dhcs.ca.gov/api/v1/Health' \
  -H 'accept: application/json' \
  -H "Authorization: Bearer $TOKEN"
HTTP/2 429
date: Mon, 27 Jan 2025 17:57:57 GMT
content-length: 0
x-envoy-ratelimited: true
server: envoy

What to do if you encounter this issue?

If you encounter this issue, simply waiting and retrying may suffice.

However, if this is burdensome your options are limited and you may need to contact the API owner and collaborate to change the rate limit. If this still doesn’t resolve your issue, submit a support request through the portal.


I just received a 401 (unauthorized), why?

Most common causes

Your request is missing a valid authentication token, or the token is invalid or expired.

Troubleshooting

Verify that a JWT token header exists

On a JWT authenticated endpoint, a JWT token header is required.

Ensure the header Authorization: Bearer $TOKEN is added to the request header:

curl -i -X 'GET' \
  'https://example-api.gateway.mes.dhcs.ca.gov/api/v1/Health' \
  -H 'accept: application/json' \
  -H "Authorization: Bearer $TOKEN"

Check for an expired JWT token

JWT tokens are short-lived. A 401 may indicate an expired token.

curl -i -X 'GET' \
  'https://example-api.gateway.mes.dhcs.ca.gov/api/v1/Health' \
  -H 'accept: application/json' \
  -H "Authorization: Bearer $TOKEN"
HTTP/2 401
date: Tue, 11 Feb 2025 21:25:09 GMT
content-type: text/plain
content-length: 14
www-authenticate: Bearer realm="https://example-api.gateway.mes.dhcs.ca.gov/api/v1/Health", error="invalid_token"
server: envoy

Verify that the JWT token is formatted correctly

JWT tokens need to be assembled in a valid format. A 401 may indicate an invalid token.

curl -i -X 'GET' \
  'https://example-api.gateway.mes.dhcs.ca.gov/api/v1/Health' \
  -H 'accept: application/json' \
  -H "Authorization: Bearer this_is_not_valid_jwt_format_token"
HTTP/2 401
date: Tue, 11 Feb 2025 21:38:17 GMT
content-type: text/plain
content-length: 79
www-authenticate: Bearer realm="https://example-api.gateway.mes.dhcs.ca.gov/api/v1/Health", error="invalid_token"
server: envoy
Jwt is not in the form of Header.Payload.Signature with two dots and 3 sections

Verify that the JWT token was generated correctly

JWT tokens are best generated from our DHCS Developer Portal. A 401 may indicate a JWT token that was created elsewhere.

Ensure that your JWT tokens are generated according to JWT Authentication with an API in the DHCS Developer Portal.


I received a 403 (forbidden), why?

Most common causes

It’s possible that the JWT token may be valid, but the audience could be incorrect. There are growing numbers of client id’s (aka audiences) and client secrets at DHCS.

Troubleshooting

Verify that your JWT token is properly configured for the API

Ensure that the all building blocks for creating your JWT token are correct for the given API according to JWT Authentication with an API in the DHCS Developer Portal.

If you suspect that JWT token is misconfigured, see the What to do if you encounter this issue section below.

Inspect your JWT token

JWT tokens are more readable than they look since they are base64url-encoded strings. jwt-cli is a handy tool to peek inside a token and explore it in a nicely formatted way. Looking inside may tell you something about why your authentication is failing.

  1. Install the JWT command line tool: brew install jwt-cli
  2. Decode your token: jwt decode <token>

Example:

jwt decode eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6ImltaTBZMnowZFlLeEJ0dEFxS19UdDVoWUJUayIsImtpZCI6ImltaTBZMnowZFlLeEJ0dEFxS19UdDVoWUJUayJ9.eyJhdWQiOiJlY2VlMzBiYS0xYTY5LTQ1NmItOTNlMy01YWZkOGE2NzhkZDYiLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC8yNjVjMmRjZC0yYTZlLTQzYWEtYjJlOC0yNjQyMWE4Yzg1MjYvIiwiaWF0IjoxNzM5MzExMjIzLCJuYmYiOjE3MzkzMTEyMjMsImV4cCI6MTczOTMxNTEyMywiYWlvIjoiazJSZ1lMQTV0MDlrZGYvdStNWG56RnQ1RldaYUFRQT0iLCJhcHBpZCI6ImVjZWUzMGJhLTFhNjktNDU2Yi05M2UzLTVhZmQ4YTY3OGRkNiIsImFwcGlkYWNyIjoiMSIsImlkcCI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0LzI2NWMyZGNkLTJhNmUtNDNhYS1iMmU4LTI2NDIxYThjODUyNi8iLCJvaWQiOiI3NzNmYzdmNS0yYjA2LTRjNmUtYmRlYS1iMzc1MmYwMTY0NmYiLCJyaCI6IjEuQVJ3QXpTMWNKbTRxcWtPeTZDWkNHb3lGSnJvdzd1eHBHbXRGay1OYV9ZcG5qZGNjQUFBY0FBLiIsInN1YiI6Ijc3M2ZjN2Y1LTJiMDYtNGM2ZS1iZGVhLWIzNzUyZjAxNjQ2ZiIsInRpZCI6IjI2NWMyZGNkLTJhNmUtNDNhYS1iMmU4LTI2NDIxYThjODUyNiIsInV0aSI6IkJja1NRbjFXcGtXVUx3aUxDZ2tWQUEiLCJ2ZXIiOiIxLjAifQ.Vah8d3173qZTkEpuchE3GRHxhJN-7c4vckdKSesIRtlONdPScvKSWEfxhax8vsN_PXmOjc5WO8vkobqQsC-53FvaGA5Qus38aqumrJE2YRSA4dym2FXqOmxjZmzk6ukrdlrOTbH7nfIsHGwZN0sqTZfpU0NamRDh_keB_Lk-DINB3e4k4Yj9bltGo9hHE-fTzzECwKjR5e83xK6ePgN7rH57zVDryTq4TkYU5qoXMrAcj5mihjrOpivpqSwJPsCCQTNMpDEgjS5pd8WCZhlmunCKA7IRv6fwXymDaMpI6Jwya8XfROFGGVR0P73GBs-6qq0SWhygnI4YZoTishwS4w

Output:

Token header
------------
{
  "typ": "JWT",
  "alg": "RS256",
  "kid": "imi0Y2z0dYKxBttAqK_Tt5hYBTk",
  "x5t": "imi0Y2z0dYKxBttAqK_Tt5hYBTk"
}

Token claims
------------
{
  "aio": "k2RgYLA5t09kdf/u+MXnzFt5FWZaAQA=",
  "appid": "ecee30ba-1a69-456b-93e3-5afd8a678dd6",
  "appidacr": "1",
  "aud": "ecee30ba-1a69-456b-93e3-5afd8a678dd6",
  "exp": 1739315123,
  "iat": 1739311223,
  "idp": "https://sts.windows.net/265c2dcd-2a6e-43aa-b2e8-26421a8c8526/",
  "iss": "https://sts.windows.net/265c2dcd-2a6e-43aa-b2e8-26421a8c8526/",
  "nbf": 1739311223,
  "oid": "773fc7f5-2b06-4c6e-bdea-b3752f01646f",
  "rh": "1.ARwAzS1cJm4qqkOy6CZCGoyFJrow7uxpGmtFk-Na_YpnjdccAAAcAA.",
  "sub": "773fc7f5-2b06-4c6e-bdea-b3752f01646f",
  "tid": "265c2dcd-2a6e-43aa-b2e8-26421a8c8526",
  "uti": "BckSQn1WpkWULwiLCgkVAA",
  "ver": "1.0"
}

Example (unexpected audience)

Here is a JWT token that was modified to change the audience to a different value to imitate what may happen if a token were generated for an unexpected audience (client id).

curl -i -X 'GET' \
  'https://example-api.gateway.mes.dhcs.ca.gov/api/v1/Health' \
  -H 'accept: application/json' \
  -H "Authorization: Bearer $TOKEN"
HTTP/2 403
date: Tue, 11 Feb 2025 22:06:39 GMT
content-type: text/plain
content-length: 32
www-authenticate: Bearer realm="https://example-api.gateway.mes.dhcs.ca.gov/api/v1/Health", error="invalid_token"
server: envoy
Audiences in Jwt are not allowed

What to do if you encounter this issue

If you suspect a missing audience configuration, your options are limited and you may need to contact the API owner to troubleshoot.

You may also repeat these steps and try again.

If this still doesn’t resolve your issue, submit a support request through the portal (see Support below).

Support

If you need assistance troubleshooting an API, require access, or having any other issues related to the API Developer Portal, please follow the instructions below to submit a support request with our online help desk.

Submitting a Request to the Help Center

Select the Support center link in the footer navigation on any page of the portal.

Submit your Request

Fill in all required fields (*) on the Support Request modal and select the Submit Request button.