quarkusio/quarkus · error · SpiffeConnectionException
Leaf certificate must contain exactly one URI SAN, found
Error message
Leaf certificate must contain exactly one URI SAN, found
What it means
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.
Source
Thrown at extensions/spiffe-client/runtime/src/main/java/io/quarkus/spiffe/client/runtime/internal/SpiffeValidator.java:180
private static String extractAndValidateUriSan(X509Certificate leaf) throws SpiffeConnectionException {
try {
var sans = leaf.getSubjectAlternativeNames();
if (sans == null || sans.isEmpty()) {
throw new SpiffeConnectionException("Leaf certificate has no Subject Alternative Names");
}
List<String> uriSans = new ArrayList<>();
for (var san : sans) {
if (san.size() > 1 && san.get(0) instanceof Integer type && type == URI_SAN_TYPE
&& san.get(1) != null) {
uriSans.add(san.get(1).toString());
}
}
if (uriSans.isEmpty()) {
throw new SpiffeConnectionException("Leaf certificate has no URI Subject Alternative Names");
}
if (uriSans.size() > 1) {
throw new SpiffeConnectionException(
"Leaf certificate must contain exactly one URI SAN, found " + uriSans.size() + ": " + uriSans);
}
return uriSans.get(0);
} catch (SpiffeConnectionException e) {
throw e;
} catch (Exception e) {
throw new SpiffeConnectionException("Failed to extract URI SAN from leaf certificate", e);
}
}
private static boolean isValidTrustDomainChar(char c) {
return (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '.' || c == '-' || c == '_';
}
private static boolean isValidPathChar(char c) {
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')
|| c == '.' || c == '-' || c == '_';
}View on GitHub (pinned to e1c734241f)
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.
Example fix
// before // subjectAltName = URI:spiffe://td/sa/a, URI:spiffe://td/sa/b // after // subjectAltName = URI:spiffe://td/sa/a
Defensive patterns
Strategy: validation
Validate before calling
long uriSanCount(X509Certificate cert) throws Exception {
var sans = cert.getSubjectAlternativeNames();
if (sans == null) return 0;
return sans.stream().filter(s -> s.size() > 1 && Integer.valueOf(6).equals(s.get(0))).count();
} Try / catch
try {
validator.validateLeaf(chain);
} catch (SpiffeConnectionException e) {
throw new IllegalStateException("SVID must contain exactly one URI SAN: " + e.getMessage(), e);
} Prevention
- 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.
When it happens
Trigger: extractAndValidateUriSan finds uriSans.size() > 1 while validating the leaf certificate during validateLeaf.
Common situations: 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.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- Leaf certificate has no URI Subject Alternative Names
- X.509-SVID certificate chain is empty
- X.509-SVID response from SPIRE agent contains a non-X.509 ce
- Signing certificate SPIFFE ID must not have a path component
- Leaf certificate has no Subject Alternative Names
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/ebec91c4b6cbad45.
Report an issue: GitHub.