juicedata/juicefs · error

error appending CA cert to pool

Error message

error appending CA cert to pool

What it means

This error is thrown when a user-supplied CA certificate PEM file is read successfully but none of its certificates could be parsed and added to the TLS root CA pool. AppendCertsFromPEM returns false when the file contains no valid PEM certificate blocks, so the TLS transport would have no trusted roots from this file.

Source

Thrown at cmd/format.go:271

			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 {
		blob, err = object.NewSharded(strings.ToLower(format.Storage), format.Bucket, format.AccessKey, format.SecretKey, format.SessionToken, format.Shards)
	} else {
		blob, err = object.CreateStorage(strings.ToLower(format.Storage), format.Bucket, format.AccessKey, format.SecretKey, format.SessionToken)
	}
	if err != nil {
		return nil, err
	}
	blob = object.WithPrefix(blob, format.Name+"/")
	initStorageTiers(blob, format.Tiers)
	if format.EncryptKey != "" {

View on GitHub (pinned to c9a67b23e8)

Solutions

  1. Verify the file contains PEM blocks starting with '-----BEGIN CERTIFICATE-----' (e.g. `grep -c 'BEGIN CERTIFICATE' ca.pem`)
  2. Convert DER certificates to PEM: `openssl x509 -inform der -in cert.der -out cert.pem`
  3. Use a known-good CA bundle (e.g. /etc/ssl/certs/ca-certificates.crt) to confirm the flag wiring works
  4. Concatenate only certificate entries: `openssl crl2pkcs7 -nocrl -certfile chain.pem | openssl pkcs7 -print_certs` to inspect what the file holds

Example fix

// before (file is DER or a key, not PEM certs)
--ca-certs client.key
// after
openssl x509 -inform der -in cert.der -out ca.pem
juicefs format --ca-certs ca.pem ...
Defensive patterns

Strategy: validation

Validate before calling

pem, err := os.ReadFile(caCertFile)
if err != nil { return err }
if !bytes.Contains(pem, []byte("-----BEGIN CERTIFICATE-----")) {
    return fmt.Errorf("%s contains no PEM certificates", caCertFile)
}

Type guard

func isPEMCertBundle(data []byte) bool {
    block, rest := pem.Decode(data)
    for block != nil {
        if block.Type == "CERTIFICATE" { return true }
        block, rest = pem.Decode(rest)
    }
    return false
}

Try / catch

if _, err := createStorage(...); err != nil {
    if strings.Contains(err.Error(), "error appending CA cert to pool") {
        // inspect the CA file: not parseable PEM certificates
    }
}

Prevention

When it happens

Trigger: Running `juicefs format` (or config/destroy/fsck/gc) with `--ca-certs` pointing to a file whose contents are not parseable PEM certificates — e.g. a public key, a private key, concatenated garbage, an empty file, or DER-encoded (binary) certificates.

Common situations: Passing a client private key file instead of a CA bundle; exporting certificates in DER format instead of PEM; a truncated or corrupted ca-certificates bundle; passing an intermediate chain without any CA certs.

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.

Related errors


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