{"record":{"id":"0b1d392d094e4373","repo":"quarkusio/quarkus","slug":"jwt-svid-aud-claim-is-not-a-string-or-array-of-s","errorCode":null,"errorMessage":"JWT-SVID 'aud' claim is not a string or array of strings","messagePattern":"JWT-SVID 'aud' claim is not a string or array of strings","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":253,"sourceCode":"        Object aud = payload.getValue(\"aud\");\n        if (aud == null) {\n            throw new SpiffeConnectionException(\"JWT-SVID from SPIRE agent is missing the required 'aud' claim\");\n        }\n        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);","sourceCodeStart":235,"sourceCodeEnd":271,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/spiffe-client/runtime/src/main/java/io/quarkus/spiffe/client/runtime/internal/SpiffeClientImpl.java#L235-L271","documentation":"The 'aud' claim must be either a single string or an array of strings. Any other JSON type (number, object, boolean, null handled separately) makes the token unparseable as a valid audience set, so SpiffeConnectionException is thrown.","triggerScenarios":"Payload contains aud as a non-string, non-array JSON value, e.g. aud: 123 or aud: {\"x\":1} in a stubbed or corrupted token.","commonSituations":"Hand-crafted test tokens with wrong claim types; scripts that build JWT payloads programmatically with incorrect serialization.","solutions":["Fix the token producer so aud is a string or array of strings","Use real SPIRE-issued JWT-SVIDs instead of synthetic ones","Validate token payloads with a JWT linter before injecting them into tests"],"exampleFix":"// before\n{\"aud\": 12345}\n// after\n{\"aud\": \"https://api.example.com\"}","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"static boolean audTypeOk(Object aud) {\n    return aud instanceof String || aud instanceof JsonArray;\n}","tryCatchPattern":"try {\n    return spiffeClient.getWorkloadJsonWebToken(audiences).await().indefinitely();\n} catch (SpiffeConnectionException e) {\n    if (e.getMessage().contains(\"not a string or array of strings\")) {\n        // fix token serialization\n    }\n    throw e;\n}","preventionTips":["Serialize aud as string or array of strings per RFC 7519","Validate generated tokens with a JWT library before injecting into tests","Avoid building JWT payload JSON by hand"],"tags":["spiffe","jwt","aud-claim","type-mismatch"],"backgroundTag":"jwt-claim-type-invalid","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}