juicedata/juicefs · error

read ca cert file error path:%s error:%s

Error message

read ca cert file error path:%s error:%s

What it means

newRedisMeta returns this when the CA certificate file given via the tls-ca-cert-file URL parameter cannot be read from disk (pkg/meta/redis.go:156). It wraps the underlying os.ReadFile error (path plus Go error), so the cause is almost always a wrong path, missing file, or permission problem. It is only raised when TLS is enabled and a CA file was explicitly configured.

Source

Thrown at pkg/meta/redis.go:156

	hosts := u.Host
	opt, err := redis.ParseURL(u.String())
	if err != nil {
		return nil, fmt.Errorf("redis parse %s: %s", uri, err)
	}
	if opt.TLSConfig != nil {
		opt.TLSConfig.ServerName = tlsServerName // use the host of each connection as ServerName
		opt.TLSConfig.InsecureSkipVerify = skipVerify != ""
		if certFile != "" {
			cert, err := tls.LoadX509KeyPair(certFile, keyFile)
			if err != nil {
				return nil, fmt.Errorf("get certificate error certFile:%s keyFile:%s error:%s", certFile, keyFile, err)
			}
			opt.TLSConfig.Certificates = []tls.Certificate{cert}
		}
		if caCertFile != "" {
			caCert, err := os.ReadFile(caCertFile)
			if err != nil {
				return nil, fmt.Errorf("read ca cert file error path:%s error:%s", caCertFile, err)
			}
			caCertPool := x509.NewCertPool()
			caCertPool.AppendCertsFromPEM(caCert)
			opt.TLSConfig.RootCAs = caCertPool
		}
	}
	if opt.Password == "" {
		opt.Password = os.Getenv("REDIS_PASSWORD")
	}
	if opt.Password == "" {
		opt.Password = os.Getenv("META_PASSWORD")
	}
	if opt.Password == "" {
		if passwordFile := os.Getenv("META_PASSWORD_FILE"); passwordFile != "" {
			password, err := readPasswordFromFile(passwordFile)
			if err != nil {
				logger.Errorf("%v", err)
			} else {

View on GitHub (pinned to c9a67b23e8)

Solutions

  1. Verify the path in tls-ca-cert-file exists and is readable: ls -l <path> and fix the typo or path.
  2. If running in a container/K8s, ensure the CA file is mounted into the pod at the referenced path.
  3. Check file permissions (chmod/chown) so the user running juicefs can read it.
  4. If the Redis server uses a CA already in the system trust store, drop the tls-ca-cert-file parameter entirely.

Example fix

// before
juicefs mount "redis://rediss-host:6379/1?tls-ca-cert-file=/etc/juicefs/ca.crt" /mnt/jfs
// error: read ca cert file error path:/etc/juicefs/ca.crt error:open ...: no such file or directory
// after: fix the path (or install the file)
juicefs mount "redis://rediss-host:6379/1?tls-ca-cert-file=/etc/ssl/juicefs/ca.pem" /mnt/jfs
Defensive patterns

Strategy: validation

Validate before calling

caPath := "/etc/ssl/juicefs/ca.pem" // value from tls-ca-cert-file
if fi, err := os.Stat(caPath); err != nil || fi.IsDir() {
    return fmt.Errorf("CA cert file %s is not a readable file", caPath)
}
if f, err := os.Open(caPath); err != nil {
    return fmt.Errorf("cannot read CA cert file %s: %w", caPath, err)
} else {
    f.Close()
}

Try / catch

if _, err := os.ReadFile(caPath); err != nil {
    // inspect err: os.IsNotExist vs permission vs is-a-directory
    log.Fatalf("bad tls-ca-cert-file %s: %v", caPath, err)
}

Prevention

When it happens

Trigger: Mounting a JuiceFS volume with a redis://...?tls-ca-cert-file=/path/to/ca.pem metadata URL where the file does not exist, is unreadable (permissions), is a directory, or the path is malformed. Happens at client startup in newRedisMeta before any Redis connection is made.

Common situations: Typo in the CA path in the mount command or systemd unit; CA file deleted or rotated by cert management (cert-manager, k8s secrets remount); running the mount in a container where the host path was not volume-mounted; running as a non-root user who cannot read the cert directory.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


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