thanos-io/thanos · error

reading client CA

Error message

reading client CA

What it means

NewServerConfig wraps an os.ReadFile failure of the client CA file with 'reading client CA'. The configured --client-ca path could not be read, so the server cannot build the client certificate pool for mTLS.

Solutions

  1. Verify the CA file exists at the exact path: ls -l and cat the file
  2. Fix the --client-ca flag or the volume/secret mount so the path matches
  3. Grant read permission to the process user
  4. Ensure the CA file is valid PEM so AppendCertsFromPEM also succeeds (a related 'building client CA' error follows otherwise)

Example fix

// before
--client-ca=/etc/thanos/ca.crt  # file not mounted
// after
# mount secret at /etc/thanos/tls then use
--client-ca=/etc/thanos/tls/ca.crt
Defensive patterns

Strategy: validation

Validate before calling

// Pre-start check
if _, err := os.ReadFile(clientCA); err != nil {
    return fmt.Errorf("client CA unreadable at %s: %w", clientCA, err)
}

Prevention

When it happens

Trigger: clientCA path is set but os.ReadFile(filepath.Clean(clientCA)) fails — file missing, wrong path, or no read permission.

Common situations: Kubernetes secret not mounted or mounted at a different path than the flag; typo in the CA path; file permissions excluding the process user; config referencing a path valid on another host.

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 thanos-io/thanos@35b8b99117 (2026-09-07). Data as JSON: /api/errors/eac2f82ae9ad74ca. Report an issue: GitHub.

Appendix: source

Thrown at pkg/tls/options.go:80

	// Certificate is loaded during server startup to check for any errors.
	certificate, err := tls.LoadX509KeyPair(certPath, keyPath)
	if err != nil {
		return nil, errors.Wrap(err, "server credentials")
	}

	mngr := &serverTLSManager{
		srvCertPath: certPath,
		srvKeyPath:  keyPath,
		srvCert:     &certificate,
	}

	tlsCfg.GetCertificate = mngr.getCertificate

	if clientCA != "" {
		caPEM, err := os.ReadFile(filepath.Clean(clientCA))
		if err != nil {
			return nil, errors.Wrap(err, "reading client CA")
		}

		certPool := x509.NewCertPool()
		if !certPool.AppendCertsFromPEM(caPEM) {
			return nil, errors.Wrap(err, "building client CA")
		}
		tlsCfg.ClientCAs = certPool
		tlsCfg.ClientAuth = tls.RequireAndVerifyClientCert

		level.Info(logger).Log("msg", "server TLS client verification enabled")
	}

	return tlsCfg, nil
}

type serverTLSManager struct {
	srvCertPath string
	srvKeyPath  string

View on GitHub (pinned to 35b8b99117)