apache/shenyu · error · ShenyuException
Could not load certificate
Error message
Could not load certificate '${trustedCert}' What it means
HttpClientProperties builds a TrustManager from the configured trusted certificates. For each trustedCert path it resolves a resource URL and parses certificates with an X.509 CertificateFactory; if reading the resource throws IOException, a ShenyuException naming the cert path is thrown during HTTP client initialization.
Solutions
- Verify the trustedCert path exists and is readable from the gateway process (use an absolute path or classpath: prefix as appropriate).
- Mount/ship the certificate file into the container/pod at the configured path.
- Fix file permissions so the gateway user can read the cert.
- Check the wrapped IOException cause for the precise reason (ENOENT vs permission vs connection for remote URLs).
Example fix
// before (application.yml) shenyu.httpclient.ssl.trusted-cert: /etc/ssl/old/ca.pem // after shenyu.httpclient.ssl.trusted-cert: /etc/ssl/certs/ca-current.pem
Defensive patterns
Strategy: validation
Validate before calling
File cert = new File(trustedCertPath);
if (!cert.isFile() || !cert.canRead()) {
throw new IllegalStateException("trustedCert not readable: " + cert.getAbsolutePath());
} Type guard
function isReadableFile(p) {
try { return require('fs').accessSync(p, require('fs').constants.R_OK) === undefined; }
catch { return false; }
} Try / catch
try {
trustManager = buildTrustManager(trustedCertPaths);
} catch (ShenyuException e) {
log.error("TLS trust material missing: {}", e.getMessage(), e);
throw new IllegalStateException("Fix trustedCert path before starting gateway", e);
} Prevention
- Use absolute paths (or explicit classpath: prefixes) for cert configuration.
- Verify cert files exist in the container image / mounted volumes at startup.
- Fail fast with a preflight check on boot instead of at first TLS use.
When it happens
Trigger: shenyu.httpclient.ssl.trustedCert (or equivalent config) points to a file that cannot be opened: wrong path, not on the classpath/filesystem, unreadable permissions, or container image missing the cert file — url.openStream() raises IOException.
Common situations: Mounting certs at a different path in Docker than configured, typo in the cert path property, relative path resolved against the wrong working directory, Kubernetes secret not mounted, cert file renamed after a rotation.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- Could not load key store path
- shenyu.jwt.secretKey is not configured. In a multi-instance…
- shenyu discovery mode current didn't support
- websocket on client open failed, namespaceId is null
- websocket sync token is not configured
AI-assisted analysis of apache/shenyu@567142e072 (2026-09-12).
Data as JSON: /api/errors/27698bea0e80e105.
Report an issue: GitHub.
Appendix: source
Thrown at shenyu-plugin/shenyu-plugin-httpclient/src/main/java/org/apache/shenyu/plugin/httpclient/config/HttpClientProperties.java:1101
/**
* Get trusted x 509 certificates for trust manager x 509 certificate [].
*
* @return the x 509 certificate []
*/
@SuppressWarnings("all")
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 = KeyManagerFactoryView on GitHub (pinned to 567142e072)