{"record":{"id":"2fcc55e417a4e948","repo":"go-task/task","slug":"failed-to-read-ca-certificate-w","errorCode":null,"errorMessage":"failed to read CA certificate: %w","messagePattern":"failed to read CA certificate: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"taskfile/node_http.go","lineNumber":48,"sourceCode":"\t// Validate that cert and certKey are provided together\n\tif (cert != \"\" && certKey == \"\") || (cert == \"\" && certKey != \"\") {\n\t\treturn nil, fmt.Errorf(\"both --cert and --cert-key must be provided together\")\n\t}\n\n\t// If no TLS customization is needed, return the default client\n\tif !insecure && caCert == \"\" && cert == \"\" {\n\t\treturn http.DefaultClient, nil\n\t}\n\n\ttlsConfig := &tls.Config{\n\t\tInsecureSkipVerify: insecure, //nolint:gosec\n\t}\n\n\t// Load custom CA certificate if provided\n\tif caCert != \"\" {\n\t\tcaCertData, err := os.ReadFile(caCert)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to read CA certificate: %w\", err)\n\t\t}\n\t\tcaCertPool := x509.NewCertPool()\n\t\tif !caCertPool.AppendCertsFromPEM(caCertData) {\n\t\t\treturn nil, fmt.Errorf(\"failed to parse CA certificate\")\n\t\t}\n\t\ttlsConfig.RootCAs = caCertPool\n\t}\n\n\t// Load client certificate and key if provided\n\tif cert != \"\" && certKey != \"\" {\n\t\tclientCert, err := tls.LoadX509KeyPair(cert, certKey)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to load client certificate: %w\", err)\n\t\t}\n\t\ttlsConfig.Certificates = []tls.Certificate{clientCert}\n\t}\n\n\treturn &http.Client{","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/go-task/task/blob/385e5ad92af02877b6d7cf9dcc963b5ed916e70a/taskfile/node_http.go#L30-L66","documentation":"When --cacert is supplied, buildHTTPClient reads the CA bundle from disk with os.ReadFile. Any read failure (missing file, permission denied, path is a directory) is wrapped as \"failed to read CA certificate\" with the OS error.","triggerScenarios":"NewHTTPNode -> buildHTTPClient with a non-empty caCert string that os.ReadFile cannot read: nonexistent path, unreadable permissions, or a directory passed as the cert file.","commonSituations":"Pointing --cacert at a directory (like the system /etc/ssl/certs) instead of a PEM bundle file; typo in the cert path; container images missing the corporate CA bundle; permission-restricted certs in CI.","solutions":["Fix the --cacert path to point at an existing PEM file the user can read","Ensure the CA bundle exists in the container/CI image (copy it in or install ca-certificates)","Check permissions: chmod 644 the CA file if needed","Look at the wrapped OS error in the message to distinguish not-found vs permission vs is-a-directory"],"exampleFix":"# before\ntask --cacert /etc/ssl/certs -f https://internal.example.com/Taskfile.yml\n# after\ntask --cacert /etc/ssl/certs/corp-root.pem -f https://internal.example.com/Taskfile.yml","handlingStrategy":"validation","validationCode":"func caCertReadable(path string) error {\n    fi, err := os.Stat(path)\n    if err != nil {\n        return fmt.Errorf(\"cacert %s: %w\", path, err)\n    }\n    if !fi.Mode().IsRegular() {\n        return fmt.Errorf(\"cacert %s is not a regular file\", path)\n    }\n    f, err := os.Open(path)\n    if err != nil {\n        return fmt.Errorf(\"cacert %s unreadable: %w\", path, err)\n    }\n    f.Close()\n    return nil\n}","typeGuard":"func isReadablePEMFile(path string) bool {\n    fi, err := os.Stat(path)\n    return err == nil && fi.Mode().IsRegular() && fi.Mode().Perm()&0o400 != 0\n}","tryCatchPattern":"node, err := taskfile.NewHTTPNode(..., caCert, ...)\nif err != nil {\n    var pe *fs.PathError\n    if errors.As(err, &pe) && strings.Contains(err.Error(), \"failed to read CA certificate\") {\n        // correct path/permissions before retrying\n    }\n    return err\n}","preventionTips":["Point --cacert at a single PEM bundle file, not a directory","Verify the cert path exists in the exact container/CI image used","Check file permissions for the user running task","Commit or mount corporate CA bundles as part of environment setup"],"tags":["http","tls","ca-cert","file-io","certificates"],"backgroundTag":"ca-cert-load-failed","analyzedSha":"385e5ad92af02877b6d7cf9dcc963b5ed916e70a","analyzedAt":"2026-09-05T09:01:05.226Z","contentChangedAt":"2026-09-05T09:01:05.226Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}