quarkusio/quarkus · error · SpiffeConnectionException

Signing certificate SPIFFE ID must not have a path component

Error message

Signing certificate SPIFFE ID must not have a path component: ${uriSan}

What it means

Per the X.509-SVID profile, if a signing certificate carries a SPIFFE ID in its URI SAN, that ID must be a trust-domain root with no path component (e.g. spiffe://example.org). SpiffeValidator.validateIntermediate rejects signing certs whose SPIFFE URI has a non-empty path, since only leaf workload identities may have paths.

Source

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

    // X.509-SVID 3.2 SHOULD: signing cert SHOULD itself be an SVID (not enforced — upstream CA may not be SPIFFE-aware)
    // X.509-SVID 3.2 SHOULD: signing cert SHOULD reside in the trust domain of leaf SVIDs it issues (not enforced — cross-domain signing is allowed)
    static void validateIntermediate(X509Certificate cert) throws SpiffeConnectionException {
        if (cert.getBasicConstraints() < 0) {
            throw new SpiffeConnectionException(
                    "Signing certificate must have CA flag set to true: " + cert.getSubjectX500Principal());
        }
        boolean[] keyUsage = cert.getKeyUsage();
        if (keyUsage == null || keyUsage.length <= 5 || !keyUsage[5]) {
            throw new SpiffeConnectionException(
                    "Signing certificate must have 'keyCertSign' as key usage: " + cert.getSubjectX500Principal());
        }
        // X.509-SVID 3.2 MUST: if signing cert has a SPIFFE ID, it must not have a path component
        String uriSan = extractOptionalUriSan(cert);
        if (uriSan != null && uriSan.startsWith(SPIFFE_URI_PREFIX)) {
            URI uri = URI.create(uriSan);
            String path = uri.getPath();
            if (path != null && !path.isEmpty() && !"/".equals(path)) {
                throw new SpiffeConnectionException(
                        "Signing certificate SPIFFE ID must not have a path component: " + uriSan);
            }
        }
    }

    static void validateSpiffeId(String spiffeId) throws SpiffeConnectionException {
        if (spiffeId == null || spiffeId.isEmpty()) {
            throw new SpiffeConnectionException("SPIFFE ID must not be empty");
        }
        if (spiffeId.length() > MAX_SPIFFE_ID_LENGTH) {
            throw new SpiffeConnectionException("SPIFFE ID exceeds maximum length of " + MAX_SPIFFE_ID_LENGTH
                    + " bytes: " + spiffeId.length());
        }

        if (!spiffeId.startsWith(SPIFFE_URI_PREFIX)) {
            throw new SpiffeConnectionException("SPIFFE ID must have 'spiffe://' scheme: " + spiffeId);
        }
        if (spiffeId.contains("%")) {

View on GitHub (pinned to e1c734241f)

Solutions

  1. Reissue the signing certificate with either no SPIFFE URI SAN or a path-less SPIFFE ID (spiffe://<trust-domain>).
  2. If the CA needs no workload identity, drop the URI SAN entirely.
  3. Fix PKI automation so SPIFFE ID paths are only applied to leaf SVIDs.

Example fix

// before
URI SAN: spiffe://example.org/sa/intermediate
// after
URI SAN: spiffe://example.org
Defensive patterns

Strategy: validation

Validate before calling

String san = extractUriSan(cert);
if (san != null && san.startsWith("spiffe://")
        && new URI(san).getPath() != null && !new URI(san).getPath().isEmpty()) {
    throw new IllegalArgumentException("CA SPIFFE ID must not have a path: " + san);
}

Try / catch

try {
    connection.establish();
} catch (SpiffeConnectionException e) {
    if (e.getMessage().contains("path component")) {
        log.error("Signing cert carries a workload-style SPIFFE ID; reissue CA cert", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: An intermediate/signing certificate contains a URI SAN like spiffe://example.org/sa/intermediate — a path component — and the chain is validated via SpiffeValidator.validateIntermediate.

Common situations: CA certs accidentally issued with workload-style identity SANs copied from a leaf template; custom PKI automation stamping the same SPIFFE ID pattern onto CAs and leaves.

Understand the failure class

Related errors


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