quarkusio/quarkus · error · SpiffeConnectionException

Leaf certificate has no Subject Alternative Names

Error message

Leaf certificate has no Subject Alternative Names

What it means

The leaf (workload) certificate presented by the SPIFFE server/workload has no Subject Alternative Names extension at all. SPIFFE identity is carried exclusively in URI SANs, so a leaf without any SAN cannot carry an identity and is rejected. This indicates a broken or non-SPIFFE certificate.

Source

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

            if (sans == null) {
                return null;
            }
            for (var san : sans) {
                if (san.size() > 1 && san.get(0) instanceof Integer type && type == URI_SAN_TYPE
                        && san.get(1) != null) {
                    return san.get(1).toString();
                }
            }
        } catch (Exception ignored) {
        }
        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;

View on GitHub (pinned to e1c734241f)

Solutions

  1. Ensure the endpoint presents a SPIFFE X.509 SVID certificate that includes the URI SAN extension.
  2. Fix the certificate-issuing template at the SPIFFE CA (e.g. SPIRE) so leaf SVIDs always include a URI SAN.
  3. Verify you are connecting to the intended SPIFFE-authenticated service, not a different TLS endpoint on the same port.

Example fix

// before: certificate profile without SAN
//   openssl req -new -key key.pem -out csr.csr  (CN only)
// after: SPIFFE SVID profile
//   subjectAltName = URI:spiffe://trust.domain/ns/default/sa/app
Defensive patterns

Strategy: validation

Validate before calling

boolean hasSan(X509Certificate cert) throws Exception {
    var sans = cert.getSubjectAlternativeNames();
    return sans != null && !sans.isEmpty();
}

Try / catch

try {
    validator.validateLeaf(chain);
} catch (SpiffeConnectionException e) {
    throw new IllegalStateException("Endpoint did not present a valid SPIFFE SVID: " + e.getMessage(), e);
}

Prevention

When it happens

Trigger: validateLeaf -> extractAndValidateUriSan is invoked during TLS trust-bundle/certificate validation when X509Certificate.getSubjectAlternativeNames() returns null or an empty collection for the leaf certificate.

Common situations: A server presents a plain TLS certificate (e.g. a default self-signed or corporate CA cert) instead of a SPIFFE workload cert; a CA issues certificates without the SAN extension due to a misconfigured certificate template.

Understand the failure class

Related errors


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