quarkusio/quarkus · error · SpiffeConnectionException

X.509-SVID response contains empty ${description}

Error message

X.509-SVID response contains empty ${description}

What it means

parseCertificates was handed a zero-length byte array for the described field (certificate chain or trust bundle). Rather than attempting to parse nothing, the client fails fast with a message identifying which field was empty. It is a precondition check guarding X.509 parsing.

Source

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

        PrivateKey privateKey;
        try {
            privateKey = KeyFactory.getInstance(keyAlgorithm)
                    .generatePrivate(new PKCS8EncodedKeySpec(svid.getX509SvidKey().toByteArray()));
        } catch (Exception e) {
            throw new SpiffeConnectionException("X.509-SVID response from SPIRE agent contains an invalid private key", e);
        }

        List<X509Certificate> trustBundle = parseCertificates(svid.getBundle().toByteArray(), "trust bundle");

        var keyMaterial = new WorkloadCertificateChainImpl(unmodifiableList(certChain), privateKey);
        var trustMaterial = new WorkloadTrustBundleImpl(unmodifiableList(trustBundle));
        return new WorkloadCertificateDocumentImpl(protoSpiffeId, keyMaterial, trustMaterial);
    }

    private static List<X509Certificate> parseCertificates(byte[] derBytes, String description)
            throws SpiffeConnectionException {
        if (derBytes.length == 0) {
            throw new SpiffeConnectionException("X.509-SVID response contains empty " + description);
        }
        try {
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            Collection<?> certs = cf.generateCertificates(new ByteArrayInputStream(derBytes));
            List<X509Certificate> result = new ArrayList<>(certs.size());
            for (var cert : certs) {
                if (cert instanceof X509Certificate x509) {
                    result.add(x509);
                } else {
                    throw new SpiffeConnectionException(
                            "X.509-SVID response from SPIRE agent contains a non-X.509 certificate in "
                                    + description + ": " + cert.getClass().getName());
                }
            }
            return result;
        } catch (Exception e) {
            throw new SpiffeConnectionException(
                    "X.509-SVID response from SPIRE agent contains an invalid " + description, e);

View on GitHub (pinned to e1c734241f)

Solutions

  1. Restart/upgrade the SPIRE agent so the SVID contains all fields.
  2. Verify the client connects to the genuine Workload API socket without an intermediate proxy.
  3. Re-request the workload certificate and compare; persistent emptiness points to agent/server sync issues.
  4. Check SPIRE registration entries and attestation status for the workload.
Defensive patterns

Strategy: validation

Try / catch

try {
    doc = client.getWorkloadCertificate();
} catch (SpiffeConnectionException e) {
    if (e.getMessage().contains("contains empty")) {
        doc = retryWithBackoff(client::getWorkloadCertificate);
    } else throw e;
}

Prevention

When it happens

Trigger: toWorkloadCertificate passing empty byte arrays from svid.getX509Svid().toByteArray() or svid.getBundle().toByteArray() into parseCertificates. In practice the earlier isEmpty() guards (2212/2214) usually catch this first.

Common situations: Mostly defensive: same root causes as empty cert chain / trust bundle — agent serving incomplete SVIDs, version mismatch, proxies truncating protobufs.

Related errors


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