prestodb/presto · error · ParseException

Unsupported 'aud' claim type in /userinfo response

Error message

Unsupported 'aud' claim type in /userinfo response

What it means

The /userinfo parser validates the 'aud' claim: it must be a string or array of strings, and the audience must include the OAuth2 client id or one of the configured access-token audiences. A claim of an unexpected JSON type throws ParseException('Unsupported 'aud' claim type in /userinfo response').

Source

Thrown at presto-main/src/main/java/com/facebook/presto/server/security/oauth2/NimbusOAuth2Client.java:621

            httpResponse.setBody(body.toJSONString());
        }

        Object audClaim = body.get("aud");
        // only validate aud claim if it exists
        if (audClaim != null) {
            List<String> audiences;

            if (audClaim instanceof String) {
                audiences = List.of((String) audClaim);
            }
            else if (audClaim instanceof List<?>) {
                audiences = ((List<?>) audClaim).stream()
                        .filter(String.class::isInstance)
                        .map(String.class::cast)
                        .collect(toImmutableList());
            }
            else {
                throw new ParseException("Unsupported 'aud' claim type in /userinfo response");
            }

            if (!audiences.contains(clientId.getValue()) && Collections.disjoint(audiences, accessTokenAudiences)) {
                throw new ParseException("Invalid audience in /userinfo response");
            }
        }

        return UserInfoSuccessResponse.parse(httpResponse);
    }

    private Optional<JWTClaimsSet> parseAccessToken(String accessToken)
    {
        try {
            return Optional.of(accessTokenProcessor.process(accessToken, null));
        }
        catch (java.text.ParseException | BadJOSEException | JOSEException e) {
            LOG.debug(e, "Failed to parse JWT access token");
            return Optional.empty();

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Inspect the raw /userinfo response and confirm the aud claim type
  2. Fix or upgrade the IdP so aud is a string or array of strings
  3. If the IdP cannot be changed, configure audiences correctly or use an IdP that emits standard OIDC claims
  4. Check for a proxy rewriting the userinfo JSON body

Example fix

// before
{"aud": {"client": "abc"}}           // object, unsupported
// after
{"aud": ["abc"]}                      // array of strings, supported
Defensive patterns

Strategy: type-guard

Validate before calling

// Pre-check the aud claim type before parsing
Object aud = userInfoJson.opt("aud");
if (aud != null && !(aud instanceof String) && !(aud instanceof org.json.JSONArray)) { throw new IllegalStateException("Unsupported aud type in /userinfo response"); }

Type guard

boolean isSupportedAudClaim(Object aud) { if (aud instanceof String) return true; if (aud instanceof org.json.JSONArray) { for (int i = 0; i < ((org.json.JSONArray) aud).length(); i++) { if (!(((org.json.JSONArray) aud).opt(i) instanceof String)) return false; } return true; } return false; }

Try / catch

try { return parseUserInfoResponse(httpResponse); } catch (com.nimbusds.oauth2.sdk.ParseException e) { if (e.getMessage().contains("aud")) { LOG.error("IdP emitted non-standard aud claim: {}", httpResponse.getBodyAsJSONObject().opt("aud")); } throw e; }

Prevention

When it happens

Trigger: The IdP returns 'aud' as a nested array of non-strings, an object, a number, or another non-string/non-list JSON type in the /userinfo response.

Common situations: Non-standard or custom IdPs emitting unusual aud representations, IdP version changes altering claim serialization, misbehaving API gateways rewriting the userinfo body.

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/0fec40c31a0ecfee. Report an issue: GitHub.