{"record":{"id":"fe62c11a24ee2e20","repo":"quarkusio/quarkus","slug":"jwt-svid-proto-spiffe-id-does-not-match-the-sub","errorCode":null,"errorMessage":"JWT-SVID proto SPIFFE ID does not match the 'sub' claim; proto: ${spiffeId}, sub: ${sub}","messagePattern":"JWT-SVID proto SPIFFE ID does not match the 'sub' claim; proto: (.+?), sub: (.+?)","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":231,"sourceCode":"                }));\n    }\n\n    private static WorkloadJsonWebToken toWorkloadJsonWebToken(JWTSVID svid,\n            Set<String> requestedAudiences) throws SpiffeConnectionException {\n        String token = svid.getSvid();\n        if (token.isBlank()) {\n            throw new SpiffeConnectionException(\"JWT-SVID from SPIRE agent has no token\");\n        }\n        String[] parts = token.split(\"\\\\.\");\n        if (parts.length != 3) {\n            throw new SpiffeConnectionException(\"JWT-SVID from SPIRE agent is not a valid JWS Compact Serialization\");\n        }\n        JsonObject payload = new JsonObject(new String(Base64.getUrlDecoder().decode(parts[1])));\n\n        String sub = payload.getString(\"sub\");\n        SpiffeValidator.validateSpiffeId(sub);\n        if (!sub.equals(svid.getSpiffeId())) {\n            throw new SpiffeConnectionException(\n                    \"JWT-SVID proto SPIFFE ID does not match the 'sub' claim; proto: \" + svid.getSpiffeId() + \", sub: \" + sub);\n        }\n\n        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            }","sourceCodeStart":213,"sourceCodeEnd":249,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/spiffe-client/runtime/src/main/java/io/quarkus/spiffe/client/runtime/internal/SpiffeClientImpl.java#L213-L249","documentation":"The 'sub' claim extracted from the decoded JWT payload is validated as a SPIFFE ID and must match the spiffe_id field of the JWTSVID proto. A mismatch means the token contents do not agree with the agent-reported identity, so the token is untrustworthy and SpiffeConnectionException is thrown.","triggerScenarios":"JWT payload sub differs from JWTSVID.getSpiffeId() — e.g. the agent returned metadata for a different workload identity than the token it issued, or the token was swapped/cached incorrectly.","commonSituations":"SPIRE agent bugs or caching stale SVIDs after registration changes; workload has multiple registration entries and identity resolution changed; tampered or replayed token in a test harness.","solutions":["Restart the SPIRE agent and re-fetch the JWT-SVID to clear stale state","Check spire-server entries for duplicate or conflicting registrations for this workload and remove duplicates","Upgrade SPIRE agent/server to a version fixing identity/proto mismatches"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    return spiffeClient.getWorkloadJsonWebToken(audiences).await().indefinitely();\n} catch (SpiffeConnectionException e) {\n    if (e.getMessage().startsWith(\"JWT-SVID proto SPIFFE ID does not match\")) {\n        // agent stale state: restart agent / re-register workload\n    }\n    throw e;\n}","preventionTips":["Restart SPIRE agents after registration changes to clear stale SVID state","Avoid duplicate registration entries for the same workload","Treat identity mismatches as security events and log them"],"tags":["spiffe","jwt","spiffe-id","integrity"],"backgroundTag":"spiffe-id-mismatch","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"}