jwtk/jjwt · error · IllegalArgumentException
Unable to access X509Certificate encoded bytes necessary to
Error message
Unable to access X509Certificate encoded bytes necessary to perform DER Base64-encoding. Certificate: {${cert}}. Cause: ${e.getMessage()} What it means
JwtX509StringConverter.applyTo encodes an X509Certificate to a Base64 DER string for the x5c header. If cert.getEncoded() throws CertificateEncodingException (the certificate provider cannot produce its DER encoding), the converter throws IllegalArgumentException with this message, embedding the certificate and cause.
Source
Thrown at impl/src/main/java/io/jsonwebtoken/impl/security/JwtX509StringConverter.java:46
public class JwtX509StringConverter implements Converter<X509Certificate, CharSequence> {
public static final JwtX509StringConverter INSTANCE = new JwtX509StringConverter();
// Returns a Base64 encoded (NOT Base64Url encoded) string of the cert's encoded byte array per
// https://www.rfc-editor.org/rfc/rfc7515.html#section-4.1.6
// https://www.rfc-editor.org/rfc/rfc7516.html#section-4.1.8
// https://www.rfc-editor.org/rfc/rfc7517.html#section-4.7
@Override
public String applyTo(X509Certificate cert) {
Assert.notNull(cert, "X509Certificate cannot be null.");
byte[] der = Bytes.EMPTY;
try {
try {
der = cert.getEncoded();
} catch (CertificateEncodingException e) {
String msg = "Unable to access X509Certificate encoded bytes necessary to perform DER " +
"Base64-encoding. Certificate: {" + cert + "}. Cause: " + e.getMessage();
throw new IllegalArgumentException(msg, e);
}
if (Bytes.isEmpty(der)) {
String msg = "X509Certificate encoded bytes cannot be null or empty. Certificate: {" + cert + "}.";
throw new IllegalArgumentException(msg);
}
return Encoders.BASE64.encode(der);
} finally {
Bytes.clear(der);
}
}
// visible for testing
protected X509Certificate toCert(final byte[] der) throws SecurityException {
return new JcaTemplate("X.509").generateX509Certificate(der);
}
@Override
public X509Certificate applyFrom(CharSequence s) {View on GitHub (pinned to fb71496164)
Solutions
- Check the wrapped cause for the provider-level encoding failure and re-load the certificate from its original PEM/DER bytes via CertificateFactory.
- Ensure the certificate was parsed by CertificateFactory.getInstance("X.509") from valid encoded bytes.
- Add/remove the BouncyCastle provider consistently so the cert's provider can encode it.
- Re-generate the certificate if the underlying object is corrupt.
Example fix
// before
X509Certificate cert = (X509Certificate) customProviderObject; // exotic impl, getEncoded fails
// after
CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509Certificate cert = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(pemBytes)); Defensive patterns
Strategy: try-catch
Validate before calling
boolean hasEncoding(X509Certificate cert) {
try { return cert.getEncoded() != null && cert.getEncoded().length > 0; }
catch (CertificateEncodingException e) { return false; }
} Try / catch
try {
String x5c = converter.applyTo(cert);
} catch (IllegalArgumentException e) {
if (e.getCause() instanceof CertificateEncodingException) {
// reload cert from PEM/DER via CertificateFactory
} else throw e;
} Prevention
- Always parse certificates with CertificateFactory.getInstance("X.509").
- Avoid passing exotic provider-backed certificate objects into JWT building.
- Test x5c header building with your real certificates in CI.
When it happens
Trigger: Building a JWS/JWT with an x5c (X.509 certificate chain) header whose certificate's getEncoded() fails, typically because the underlying provider cannot encode the certificate format.
Common situations: Certificates loaded from non-standard providers or exotic formats (e.g. a certificate implementation backed by an unsupported provider); corrupted or partially parsed certificate objects; provider mismatch after moving keys between JVM security providers (BouncyCastle vs default SUN).
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- X509Certificate encoded bytes cannot be null or empty. Cert
- Unable to convert Base64 String '${s}' to X509Certificate in
- Unable to encode input: ${e.getMessage()}
- Unable to ${codecName}-encode ${name}: ${t.getMessage()}
- JWK Set map keys must be Strings. Encountered key '${key}' o
AI-assisted analysis of jwtk/jjwt@fb71496164 (2026-09-09).
Data as JSON: /api/errors/6bd564daf11133a9.
Report an issue: GitHub.