{"record":{"id":"915ebbda2f1f77be","repo":"containerd/containerd","slug":"unable-to-read-ca-cert-q-w","errorCode":null,"errorMessage":"unable to read CA cert %q: %w","messagePattern":"unable to read CA cert %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/remotes/docker/config/hosts.go","lineNumber":258,"sourceCode":"}\n\nfunc updateTLSConfigFromHost(tlsConfig *tls.Config, host *hostConfig) error {\n\tif host.skipVerify != nil {\n\t\ttlsConfig.InsecureSkipVerify = *host.skipVerify\n\t}\n\n\tif host.caCerts != nil {\n\t\tif tlsConfig.RootCAs == nil {\n\t\t\trootPool, err := x509.SystemCertPool()\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"unable to initialize cert pool: %w\", err)\n\t\t\t}\n\t\t\ttlsConfig.RootCAs = rootPool\n\t\t}\n\t\tfor _, f := range host.caCerts {\n\t\t\tdata, err := os.ReadFile(f)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"unable to read CA cert %q: %w\", f, err)\n\t\t\t}\n\t\t\tif !tlsConfig.RootCAs.AppendCertsFromPEM(data) {\n\t\t\t\treturn fmt.Errorf(\"unable to load CA cert %q\", f)\n\t\t\t}\n\t\t}\n\t}\n\n\tfor _, pair := range host.clientPairs {\n\t\tcertPEMBlock, err := os.ReadFile(pair[0])\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"unable to read CERT file %q: %w\", pair[0], err)\n\t\t}\n\t\tvar keyPEMBlock []byte\n\t\tif pair[1] != \"\" {\n\t\t\tkeyPEMBlock, err = os.ReadFile(pair[1])\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"unable to read CERT file %q: %w\", pair[1], err)\n\t\t\t}","sourceCodeStart":240,"sourceCodeEnd":276,"githubUrl":"https://github.com/containerd/containerd/blob/4246446a2bf7d03837b0244118d858799393bd80/core/remotes/docker/config/hosts.go#L240-L276","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Fix the path in hosts.toml to the actual cert file location","Mount or copy the CA file into the container/pod and confirm with ls -l","Fix file permissions so the containerd user can read it","Use an absolute path; containerd does not resolve hosts.toml CA entries relative to arbitrary working dirs"],"exampleFix":"# before (hosts.toml)\n[host.\"https://registry.example.com\"]\n  ca = \"/etc/containerd/certs.d/myca.crt\"   # file doesn't exist\n# after\n  ca = \"/etc/containerd/certs.d/registry.example.com/myca.crt\"","handlingStrategy":"validation","validationCode":"for _, ca := range caPaths {\n    if _, err := os.ReadFile(ca); err != nil {\n        return fmt.Errorf(\"CA %s unreadable before configuring host: %w\", ca, err)\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use absolute paths in hosts.toml ca entries","Mount CA files via secrets and verify at pod startup","Check readability as the containerd service user","Validate hosts.toml with containerd config check after edits"],"tags":["tls","certificates","file-not-found","config"],"backgroundTag":"ca-cert-file-not-found","analyzedSha":"4246446a2bf7d03837b0244118d858799393bd80","analyzedAt":"2026-09-02T00:14:43.053Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}