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

  1. Verify ssl-cert and ssl-key paths exist and are readable from the client's working directory.
  2. Ensure both files are PEM-encoded (BEGIN CERTIFICATE / BEGIN PRIVATE KEY).
  3. Confirm the certificate and key are a matching pair (compare modulus/public key hashes).
  4. 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

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.

Related errors


AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06). Data as JSON: /api/errors/c76279ec49a52019. Report an issue: GitHub.