quarkusio/quarkus · error · SpiffeConnectionException

Leaf certificate has no URI Subject Alternative Names

Error message

Leaf certificate has no URI Subject Alternative Names

What it means

The leaf certificate has SAN entries, but none of them is of type URI (type 7). SPIFFE requires exactly one URI SAN holding the spiffe:// identity; DNS/IP SANs alone do not qualify. The certificate is therefore not a valid SVID.

Source

Thrown at extensions/spiffe-client/runtime/src/main/java/io/quarkus/spiffe/client/runtime/internal/SpiffeValidator.java:177

        }
        return null;
    }

    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) {

View on GitHub (pinned to e1c734241f)

Solutions

  1. Issue a proper SPIFFE X.509 SVID with a URI SAN of the form spiffe://<trust-domain>/<path>.
  2. Replace legacy DNS-SAN-only certificates at the server side with SVIDs from your SPIRE/Workload API.
  3. Check CA certificate profiles to guarantee the SAN type is uniformResourceIdentifier (7).

Example fix

// before
//   subjectAltName = DNS:svc.example.com
// after
//   subjectAltName = URI:spiffe://example.org/ns/default/sa/svc
Defensive patterns

Strategy: validation

Validate before calling

boolean hasUriSan(X509Certificate cert) throws Exception {
    var sans = cert.getSubjectAlternativeNames();
    if (sans == null) return false;
    return sans.stream().anyMatch(s -> s.size() > 1 && Integer.valueOf(6).equals(s.get(0)));
}

Try / catch

try {
    validator.validateLeaf(chain);
} catch (SpiffeConnectionException e) {
    throw new IllegalStateException("SVID lacks a URI SAN — reissue from SPIRE: " + e.getMessage(), e);
}

Prevention

When it happens

Trigger: extractAndValidateUriSan collects only SAN entries whose type equals URI_SAN_TYPE; when none exist (e.g. only dNSName entries) it throws this error during validateLeaf.

Common situations: Certificates generated with only DNS SANs (typical TLS server certs) are used where SPIFFE SVIDs are expected; migration from traditional mTLS to SPIFFE where old certificates remain deployed.

Understand the failure class

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/5413d61da3552889. Report an issue: GitHub.