containerd/containerd · error

unable to read CA cert %q: %w

Error message

unable to read CA cert %q: %w

What it means

A CA certificate file listed in the host configuration (hosts.toml 'ca' entry) could not be read from disk. The error wraps the os.ReadFile failure, so the cause is typically ENOENT or a permissions problem. It stops TLS setup for that host because the trust anchors cannot be loaded.

Source

Thrown at core/remotes/docker/config/hosts.go:258

}

func updateTLSConfigFromHost(tlsConfig *tls.Config, host *hostConfig) error {
	if host.skipVerify != nil {
		tlsConfig.InsecureSkipVerify = *host.skipVerify
	}

	if host.caCerts != nil {
		if tlsConfig.RootCAs == nil {
			rootPool, err := x509.SystemCertPool()
			if err != nil {
				return fmt.Errorf("unable to initialize cert pool: %w", err)
			}
			tlsConfig.RootCAs = rootPool
		}
		for _, f := range host.caCerts {
			data, err := os.ReadFile(f)
			if err != nil {
				return fmt.Errorf("unable to read CA cert %q: %w", f, err)
			}
			if !tlsConfig.RootCAs.AppendCertsFromPEM(data) {
				return fmt.Errorf("unable to load CA cert %q", f)
			}
		}
	}

	for _, pair := range host.clientPairs {
		certPEMBlock, err := os.ReadFile(pair[0])
		if err != nil {
			return fmt.Errorf("unable to read CERT file %q: %w", pair[0], err)
		}
		var keyPEMBlock []byte
		if pair[1] != "" {
			keyPEMBlock, err = os.ReadFile(pair[1])
			if err != nil {
				return fmt.Errorf("unable to read CERT file %q: %w", pair[1], err)
			}

View on GitHub (pinned to 4246446a2b)

Solutions

  1. Fix the path in hosts.toml to the actual cert file location
  2. Mount or copy the CA file into the container/pod and confirm with ls -l
  3. Fix file permissions so the containerd user can read it
  4. Use an absolute path; containerd does not resolve hosts.toml CA entries relative to arbitrary working dirs

Example fix

# before (hosts.toml)
[host."https://registry.example.com"]
  ca = "/etc/containerd/certs.d/myca.crt"   # file doesn't exist
# after
  ca = "/etc/containerd/certs.d/registry.example.com/myca.crt"
Defensive patterns

Strategy: validation

Validate before calling

for _, ca := range caPaths {
    if _, err := os.ReadFile(ca); err != nil {
        return fmt.Errorf("CA %s unreadable before configuring host: %w", ca, err)
    }
}

Prevention

When it happens

Trigger: updateTLSConfigFromHost iterates host.caCerts and os.ReadFile(f) fails for one of the configured paths — file deleted, wrong path in hosts.toml, or unreadable permissions/secrets not mounted.

Common situations: Typo or wrong absolute path in /etc/containerd/certs.d/<host>/hosts.toml; Kubernetes secret volume not mounted into the containerd pod; file removed after base-image slimming; relative path used where absolute is required.

Related errors


AI-assisted analysis of containerd/containerd@4246446a2b (2026-09-02). Data as JSON: /api/errors/915ebbda2f1f77be. Report an issue: GitHub.