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
- Reissue the client certificate including a URI SAN of the form spiffe://<trust-domain>/<path>.
- Fix the cert-issuing template (e.g. SPIRE/openssl config) to add the SPIFFE ID as a uniformResourceIdentifier SAN.
- Verify with: openssl x509 -in cert.pem -text | grep -A2 'URI' — a spiffe:// URI must be present.
- 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
- Always issue client certs with a spiffe:// URI SAN.
- Check certs with openssl before deployment.
- Align cert templates with SPIRE/SPIFFE trust-domain naming.
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
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- Configured node identity is not matching identity extractedf
- MutualTlsInternodeAuthenticator requires server_encryption_o
- MutualTlsWithPasswordFallbackAuthenticator requires client_e
- legacy_ssl_storage_port_enabled is true (enabled) with inter
- Unrecognized TLS encryption policy:
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/df35d9f98acc93d3.
Report an issue: GitHub.