{"record":{"id":"ebec91c4b6cbad45","repo":"quarkusio/quarkus","slug":"leaf-certificate-must-contain-exactly-one-uri-san","errorCode":null,"errorMessage":"Leaf certificate must contain exactly one URI SAN, found ","messagePattern":"Leaf certificate must contain exactly one URI SAN, found ","errorType":"exception","errorClass":"SpiffeConnectionException","httpStatus":null,"severity":"error","filePath":"extensions/spiffe-client/runtime/src/main/java/io/quarkus/spiffe/client/runtime/internal/SpiffeValidator.java","lineNumber":180,"sourceCode":"\n    private static String extractAndValidateUriSan(X509Certificate leaf) throws SpiffeConnectionException {\n        try {\n            var sans = leaf.getSubjectAlternativeNames();\n            if (sans == null || sans.isEmpty()) {\n                throw new SpiffeConnectionException(\"Leaf certificate has no Subject Alternative Names\");\n            }\n            List<String> uriSans = new ArrayList<>();\n            for (var san : sans) {\n                if (san.size() > 1 && san.get(0) instanceof Integer type && type == URI_SAN_TYPE\n                        && san.get(1) != null) {\n                    uriSans.add(san.get(1).toString());\n                }\n            }\n            if (uriSans.isEmpty()) {\n                throw new SpiffeConnectionException(\"Leaf certificate has no URI Subject Alternative Names\");\n            }\n            if (uriSans.size() > 1) {\n                throw new SpiffeConnectionException(\n                        \"Leaf certificate must contain exactly one URI SAN, found \" + uriSans.size() + \": \" + uriSans);\n            }\n            return uriSans.get(0);\n        } catch (SpiffeConnectionException e) {\n            throw e;\n        } catch (Exception e) {\n            throw new SpiffeConnectionException(\"Failed to extract URI SAN from leaf certificate\", e);\n        }\n    }\n\n    private static boolean isValidTrustDomainChar(char c) {\n        return (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '.' || c == '-' || c == '_';\n    }\n\n    private static boolean isValidPathChar(char c) {\n        return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')\n                || c == '.' || c == '-' || c == '_';\n    }","sourceCodeStart":162,"sourceCodeEnd":198,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/spiffe-client/runtime/src/main/java/io/quarkus/spiffe/client/runtime/internal/SpiffeValidator.java#L162-L198","documentation":"SPIFFE X.509 SVIDs must contain exactly one URI SAN. The leaf certificate carries multiple URI SANs, which violates the SPIFFE specification, so the validator refuses it because the identity would be ambiguous.","triggerScenarios":"extractAndValidateUriSan finds uriSans.size() > 1 while validating the leaf certificate during validateLeaf.","commonSituations":"Custom CAs issuing certificates that bundle several identities in one cert; concatenating SAN lists in certificate templates; old tooling that adds both a service and host URI SAN.","solutions":["Re-issue the leaf certificate with a single URI SAN containing the workload's SPIFFE ID.","Fix the CA/issuance code that appends multiple URI SANs to one certificate.","If multiple identities are needed, issue separate SVIDs rather than packing them into one certificate."],"exampleFix":"// before\n//   subjectAltName = URI:spiffe://td/sa/a, URI:spiffe://td/sa/b\n// after\n//   subjectAltName = URI:spiffe://td/sa/a","handlingStrategy":"validation","validationCode":"long uriSanCount(X509Certificate cert) throws Exception {\n    var sans = cert.getSubjectAlternativeNames();\n    if (sans == null) return 0;\n    return sans.stream().filter(s -> s.size() > 1 && Integer.valueOf(6).equals(s.get(0))).count();\n}","typeGuard":null,"tryCatchPattern":"try {\n    validator.validateLeaf(chain);\n} catch (SpiffeConnectionException e) {\n    throw new IllegalStateException(\"SVID must contain exactly one URI SAN: \" + e.getMessage(), e);\n}","preventionTips":["Issue one SVID per workload identity instead of multiple URI SANs per certificate.","Review custom CA issuance code that appends extra URI SANs.","Add a pre-deployment check asserting single URI SAN in leaf certs."],"tags":["spiffe","certificate","x509","san"],"backgroundTag":"multiple-uri-san","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"}