apache/cassandra · error · CertificateException

Unable to extract Spiffe from the certificate

Error message

Unable to extract Spiffe from the certificate

What it means

SpiffeCertificateValidator.getSANSpiffe() scans the client certificate's Subject Alternative Names for a URI entry starting with spiffe://. If no such SAN is found, it throws a CertificateException meaning the presented certificate cannot be used to establish a SPIFFE identity for mTLS authentication/authorization.

Source

Thrown at src/java/org/apache/cassandra/auth/SpiffeCertificateValidator.java:97

    private static String getSANSpiffe(final Certificate[] clientCertificates) throws CertificateException
    {
        int URI_TYPE = 6;
        X509Certificate[] castedCerts = castCertsToX509(clientCertificates);
        Collection<List<?>> subjectAltNames = castedCerts[0].getSubjectAlternativeNames();

        if (subjectAltNames != null)
        {
            for (List<?> item : subjectAltNames)
            {
                Integer type = (Integer) item.get(0);
                String spiffe = (String) item.get(1);
                if (type == URI_TYPE && spiffe.startsWith("spiffe://"))
                {  // Spiffe is a URI
                    return spiffe;
                }
            }
        }
        throw new CertificateException("Unable to extract Spiffe from the certificate");
    }
}

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Reissue the client certificate including a URI SAN of the form spiffe://<trust-domain>/<path>.
  2. Fix the cert-issuing template (e.g. SPIRE/openssl config) to add the SPIFFE ID as a uniformResourceIdentifier SAN.
  3. Verify with: openssl x509 -in cert.pem -text | grep -A2 'URI' — a spiffe:// URI must be present.
  4. If SPIFFE validation is not intended, switch the certificate validator configuration to a non-Spiffe validator.

Example fix

// before (openssl extfile without spiffe)
subjectAltName = DNS:client.example.com
// after
subjectAltName = DNS:client.example.com,URI:spiffe://example.org/ns/default/sa/client
Defensive patterns

Strategy: validation

Validate before calling

// Verify before configuring SpiffeCertificateValidator:
Collection<List<?>> sans = cert.getSubjectAlternativeNames();
boolean hasSpiffe = sans != null && sans.stream()
    .anyMatch(s -> s.size() > 1 && s.get(0) == 6 && String.valueOf(s.get(1)).startsWith("spiffe://"));
if (!hasSpiffe) throw new IllegalStateException("Certificate lacks spiffe:// URI SAN");

Type guard

boolean hasSpiffeUriSAN(X509Certificate cert) throws CertificateParsingException {
    return cert.getSubjectAlternativeNames() != null && cert.getSubjectAlternativeNames().stream()
        .anyMatch(s -> Integer.valueOf(6).equals(s.get(0))
            && String.valueOf(s.get(1)).startsWith("spiffe://"));
}

Try / catch

try {
    String id = validator.identity(cert);
} catch (CertificateException e) {
    log.error("No SPIFFE ID in client certificate SANs; reissue cert with spiffe:// URI SAN");
}

Prevention

When it happens

Trigger: A client presents a certificate during TLS handshake whose SANs contain no URI type entry with a spiffe:// prefix; identity() then fails to extract the Spiffe ID.

Common situations: Certificates issued by an internal CA without SPIFFE URI SANs; misconfigured workload/issuer templates (DNS SANs only); using a server cert that lacks the SPIFFE identity extension.

Understand the failure class

Related errors


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/df35d9f98acc93d3. Report an issue: GitHub.