juicedata/juicefs · error
error loading certificate and key file: %s
Error message
error loading certificate and key file: %s
What it means
When the object storage URL carries `ca-certs`, `ssl-cert`, and `ssl-key` query parameters, createStorage configures client-side TLS via tls.LoadX509KeyPair. This error means Go's TLS loader could not read or parse the certificate/key files (bad path, wrong PEM format, mismatched pair, or encrypted key without password support).
Source
Thrown at cmd/format.go:261
if u, err := url.Parse(format.Bucket); err == nil {
values := u.Query()
if values.Get("tls-insecure-skip-verify") != "" {
var tlsSkipVerify bool
if tlsSkipVerify, err = strconv.ParseBool(values.Get("tls-insecure-skip-verify")); err != nil {
return nil, err
}
object.GetHttpClient().Transport.(*http.Transport).TLSClientConfig.InsecureSkipVerify = tlsSkipVerify
values.Del("tls-insecure-skip-verify")
u.RawQuery = values.Encode()
format.Bucket = u.String()
}
// Configure client TLS when params are provided
if values.Get("ca-certs") != "" && values.Get("ssl-cert") != "" && values.Get("ssl-key") != "" {
clientTLSCert, err := tls.LoadX509KeyPair(values.Get("ssl-cert"), values.Get("ssl-key"))
if err != nil {
return nil, fmt.Errorf("error loading certificate and key file: %s", err.Error())
}
certPool := x509.NewCertPool()
caCertPEM, err := os.ReadFile(values.Get("ca-certs"))
if err != nil {
return nil, fmt.Errorf("error loading CA cert file: %s", err.Error())
}
if certAdded := certPool.AppendCertsFromPEM(caCertPEM); !certAdded {
return nil, fmt.Errorf("error appending CA cert to pool")
}
object.GetHttpClient().Transport.(*http.Transport).TLSClientConfig.RootCAs = certPool
object.GetHttpClient().Transport.(*http.Transport).TLSClientConfig.Certificates = []tls.Certificate{clientTLSCert}
}
}
if format.Shards > 1 {View on GitHub (pinned to c9a67b23e8)
Solutions
- Verify ssl-cert and ssl-key paths exist and are readable from the client's working directory.
- Ensure both files are PEM-encoded (BEGIN CERTIFICATE / BEGIN PRIVATE KEY).
- Confirm the certificate and key are a matching pair (compare modulus/public key hashes).
- Remove/rename the TLS params in the bucket URL if client TLS is not actually required.
Example fix
// before object storage url: s3://bucket?ca-certs=/etc/certs/ca.crt&ssl-cert=/etc/certs/client.crt&ssl-key=/etc/certs/old.key // after object storage url: s3://bucket?ca-certs=/etc/certs/ca.crt&ssl-cert=/etc/certs/client.crt&ssl-key=/etc/certs/client.key
Defensive patterns
Strategy: validation
Validate before calling
if _, err := tls.LoadX509KeyPair(sslCert, sslKey); err != nil {
return fmt.Errorf("client TLS pair invalid before mount: %w", err)
} Try / catch
clientTLSCert, err := tls.LoadX509KeyPair(cert, key)
if err != nil {
return nil, fmt.Errorf("error loading certificate and key file: %s", err.Error())
} Prevention
- Use absolute paths for ssl-cert/ssl-key in the storage URL.
- Keep cert and key files together in one directory and rotate them as a pair.
- Ensure PEM format (not DER); convert with `openssl x509 -in cert.der -outform PEM`.
- Verify the pair matches: compare `openssl x509 -noout -modulus` and `openssl rsa -noout -modulus` hashes.
When it happens
Trigger: `juicefs mount`/`format` with a storage URL like `...?ca-certs=ca.pem&ssl-cert=client.pem&ssl-key=client.key` where any of the cert/key files is missing, unreadable, malformed, or the cert and key do not form a matching pair.
Common situations: Typo in file paths relative to working directory; certificate file in DER instead of PEM; cert and key from different issuers; files unreadable due to permissions (or not present inside container image).
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
- error appending CA cert to pool
- error loading CA cert file: %s
- build tls config from %s: %s
- ceph: can't put empty file
- GOOGLE_CLOUD_PROJECT environment variable must be set
AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06).
Data as JSON: /api/errors/c76279ec49a52019.
Report an issue: GitHub.