apache/shenyu · error · ShenyuException

Could not load CertificateFactory X.509

Error message

Could not load CertificateFactory X.509

What it means

In the same trust-material setup, CertificateFactory.getInstance("X.509") (or equivalent) throwing CertificateException means the JVM could not provide an X.509 certificate factory. The code rethrows it as ShenyuException 'Could not load CertificateFactory X.509'.

Solutions

  1. Restore the default security providers: check the JVM's java.security file for modified security.provider entries.
  2. Run with a standard JDK/JRE distribution (e.g. Temurin 17) instead of a stripped custom image.
  3. Inspect the wrapped CertificateException for provider-specific details.
  4. As a workaround, register a provider that supplies the X.509 CertificateFactory.

Example fix

// before (java.security)
# security.provider.1=sun.security.provider.SunSecurityProvider  (commented out)
// after
security.provider.1=sun.security.provider.Sun
security.provider.2=org.bouncycastle.jce.provider.BouncyCastle
Defensive patterns

Strategy: try-catch

Validate before calling

try {
  java.security.cert.CertificateFactory.getInstance("X.509");
} catch (java.security.cert.CertificateException e) {
  throw new IllegalStateException("JVM lacks X.509 CertificateFactory provider", e);
}

Try / catch

try {
  initTlsContext();
} catch (ShenyuException e) {
  if (e.getMessage().contains("CertificateFactory")) {
    log.error("JDK security providers broken — restore default java.security", e);
  }
  throw e;
}

Prevention

When it happens

Trigger: CertificateFactory X.509 instantiation fails while initializing the HTTP client's trust manager — effectively only when the JDK's security providers are broken, a custom provider list removes the standard X.509 factory, or the JVM's security config (java.security) is tampered with.

Common situations: Custom JRE builds with stripped security providers, overridden java.security file in the container, misconfigured security.provider entries, unusual JDK distributions.

Understand the failure class

Related errors


AI-assisted analysis of apache/shenyu@567142e072 (2026-09-12). Data as JSON: /api/errors/a6b3513f64bdaf6c. Report an issue: GitHub.

Appendix: source

Thrown at shenyu-plugin/shenyu-plugin-httpclient/src/main/java/org/apache/shenyu/plugin/httpclient/config/HttpClientProperties.java:1107

        public X509Certificate[] getTrustedX509CertificatesForTrustManager() {
            try {
                CertificateFactory certificateFactory = CertificateFactory
                        .getInstance("X.509");
                List<Certificate> allCerts = new ArrayList<>();
                for (String trustedCert : ssl.getTrustedX509Certificates()) {
                    try {
                        URL url = ResourceUtils.getURL(trustedCert);
                        Collection<? extends Certificate> certs = certificateFactory
                                .generateCertificates(url.openStream());
                        allCerts.addAll(certs);
                    } catch (IOException e) {
                        throw new ShenyuException(
                                "Could not load certificate '" + trustedCert + "'", e);
                    }
                }
                return allCerts.toArray(new X509Certificate[allCerts.size()]);
            } catch (CertificateException e) {
                throw new ShenyuException("Could not load CertificateFactory X.509", e);
            }
        }
    
        /**
         * Gets key manager factory.
         *
         * @return the key manager factory
         */
        public KeyManagerFactory getKeyManagerFactory() {
            try {
                if (StringUtils.isNotEmpty(getKeyStorePath())) {
                    KeyManagerFactory keyManagerFactory = KeyManagerFactory
                            .getInstance(KeyManagerFactory.getDefaultAlgorithm());
                    char[] keyPassword = Optional.ofNullable(getKeyPassword())
                            .map(String::toCharArray).orElse(getKeyStorePassword().toCharArray());
                    keyManagerFactory.init(this.createKeyStore(), keyPassword);
                    return keyManagerFactory;
                }

View on GitHub (pinned to 567142e072)