{"record":{"id":"f379f2c3a8d73ead","repo":"quarkusio/quarkus","slug":"jwt-svid-aud-claim-does-not-contain-the-requeste","errorCode":null,"errorMessage":"JWT-SVID 'aud' claim does not contain the requested audiences; requested: ${requestedAudiences}, received: ${audience}","messagePattern":"JWT-SVID 'aud' claim does not contain the requested audiences; requested: (.+?), received: (.+?)","errorType":"exception","errorClass":"SpiffeConnectionException","httpStatus":null,"severity":"error","filePath":"extensions/spiffe-client/runtime/src/main/java/io/quarkus/spiffe/client/runtime/internal/SpiffeClientImpl.java","lineNumber":257,"sourceCode":"        final Set<String> audience;\n        if (aud instanceof JsonArray audienceAsArray) {\n            audience = new HashSet<>(audienceAsArray.size());\n            for (int i = 0; i < audienceAsArray.size(); i++) {\n                if (audienceAsArray.getValue(i) instanceof String audienceAsString) {\n                    audience.add(audienceAsString);\n                } else {\n                    throw new SpiffeConnectionException(\n                            \"JWT-SVID 'aud' array element at index \" + i + \" is not a string:\" + audienceAsArray.getValue(i));\n                }\n            }\n        } else if (aud instanceof String audienceAsString) {\n            audience = Set.of(audienceAsString);\n        } else {\n            throw new SpiffeConnectionException(\n                    \"JWT-SVID 'aud' claim is not a string or array of strings\");\n        }\n        if (!audience.containsAll(requestedAudiences)) {\n            throw new SpiffeConnectionException(\n                    \"JWT-SVID 'aud' claim does not contain the requested audiences; requested: \"\n                            + requestedAudiences + \", received: \" + audience);\n        }\n        if (audience.size() != requestedAudiences.size()) {\n            throw new SpiffeConnectionException(\n                    \"JWT-SVID 'aud' claim contains unexpected extra audiences; requested: \"\n                            + requestedAudiences + \", received: \" + audience);\n        }\n\n        Long exp = payload.getLong(\"exp\");\n        if (exp == null) {\n            throw new SpiffeConnectionException(\"JWT-SVID from SPIRE agent is missing the required 'exp' claim\");\n        }\n        Instant expiry = Instant.ofEpochSecond(exp);\n        if (expiry.isBefore(Instant.now())) {\n            throw new SpiffeConnectionException(\"JWT-SVID from SPIRE agent is already expired\");\n        }\n","sourceCodeStart":239,"sourceCodeEnd":275,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/spiffe-client/runtime/src/main/java/io/quarkus/spiffe/client/runtime/internal/SpiffeClientImpl.java#L239-L275","documentation":"After parsing the token's aud claim, the client requires that it covers all requested audiences. If any audience passed to getWorkloadJsonWebToken is absent from the token's aud, the SVID cannot be used for the intended call and SpiffeConnectionException is thrown.","triggerScenarios":"Calling getWorkloadJsonWebToken(Set.of(\"a\",\"b\")) while the SPIRE agent issues a token whose aud contains only \"a\"; requesting an audience the workload's registration entry doesn't allow.","commonSituations":"Audience configured in the app (e.g. OIDC token audience) differs from what the SPIRE entry issues; SPIRE agent substituting audiences when -audience isn't honored; changed upstream service audience value after a rename.","solutions":["Update the SPIRE registration entry (spire-server entry update) so it permits all required audiences for the workload","Align the audiences passed to getWorkloadJsonWebToken with the audiences actually granted by the entry","Check quarkus.spiffe / OIDC audience configuration so requested audiences match the target service expectations"],"exampleFix":"// before\nspiffeClient.getWorkloadJsonWebToken(Set.of(\"https://new-api.example.com\"));\n// after (entry only grants the legacy audience until updated)\nspiffeClient.getWorkloadJsonWebToken(Set.of(\"https://api.example.com\"));","handlingStrategy":"validation","validationCode":"// ensure requested audiences are those the SPIRE entry grants\nSet<String> requested = Set.of(\"https://api.example.com\");\nif (requested.isEmpty()) throw new IllegalStateException(\"no audiences configured\");\n// keep requested in sync with spire-server entry show output","typeGuard":null,"tryCatchPattern":"try {\n    return spiffeClient.getWorkloadJsonWebToken(requested).await().indefinitely();\n} catch (SpiffeConnectionException e) {\n    if (e.getMessage().startsWith(\"JWT-SVID 'aud' claim does not contain\")) {\n        // update SPIRE entry or align requested audiences\n    }\n    throw e;\n}","preventionTips":["Keep app-configured audiences in sync with SPIRE registration entries","Re-check entries after audience renames in upstream services","Test end-to-end with spire-agent api fetch jwt -audience before deploying"],"tags":["spiffe","jwt","aud-claim","audience-mismatch"],"backgroundTag":"jwt-audience-mismatch","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}