{"record":{"id":"76770829e8156ee9","repo":"argoproj/argo-workflows","slug":"failed-to-read-certificate-authority-w","errorCode":null,"errorMessage":"failed to read certificate authority: %w","messagePattern":"failed to read certificate authority: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"util/tls/tls.go","lineNumber":169,"sourceCode":"\t}, nil\n}\n\n// GetClientTLSConfig creates a TLS 1.2 or newer configuration for client connections.\n// Client certificate authentication requires both clientCert and clientKey. If caCert is provided,\n// the certificate authority is used instead of the system roots to verify the server certificate.\n// The insecureSkipVerify parameter controls whether the server's certificate is verified.\nfunc GetClientTLSConfig(clientCert, clientKey, caCert string, insecureSkipVerify bool) (*tls.Config, error) {\n\ttlsConfig := &tls.Config{\n\t\tInsecureSkipVerify: insecureSkipVerify,\n\t\tMinVersion:         tls.VersionTLS12,\n\t}\n\tif (clientCert == \"\") != (clientKey == \"\") {\n\t\treturn nil, fmt.Errorf(\"client certificate authentication requires both clientCert and clientKey\")\n\t}\n\tif caCert != \"\" {\n\t\tcaPEM, err := os.ReadFile(caCert)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to read certificate authority: %w\", err)\n\t\t}\n\t\tcertPool := x509.NewCertPool()\n\t\tif ok := certPool.AppendCertsFromPEM(caPEM); !ok {\n\t\t\treturn nil, fmt.Errorf(\"failed to parse certificate authority %q\", caCert)\n\t\t}\n\t\ttlsConfig.RootCAs = certPool\n\t}\n\tif clientCert != \"\" && clientKey != \"\" {\n\t\tcert, err := tls.LoadX509KeyPair(clientCert, clientKey)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\ttlsConfig.Certificates = []tls.Certificate{cert}\n\t}\n\treturn tlsConfig, nil\n}\n","sourceCodeStart":151,"sourceCodeEnd":186,"githubUrl":"https://github.com/argoproj/argo-workflows/blob/35bff19146f5a6ada77468c431f2624bd577e373/util/tls/tls.go#L151-L186","documentation":"GetClientTLSConfig could not read the CA certificate file at the given path. The wrapped os.ReadFile error names the actual OS problem (missing file, permissions, etc.). This is used to build the RootCAs pool for verifying the Argo server certificate.","triggerScenarios":"Calling GetClientTLSConfig with a non-empty caCert path that cannot be opened — file does not exist, wrong path, unreadable permissions, or the secret volume isn't mounted yet.","commonSituations":"Pointing the argo CLI at a CA path from a different machine/host; k8s secret volume not mounted into the pod; path typo; running outside the cluster where the in-cluster CA file doesn't exist; RBAC/volume mount missing after upgrade.","solutions":["Verify the caCert path exists and is readable by the process (ls -l; check mount)","Fix the path in your CLI flag / env var / config so it points at the actual CA PEM file","If in Kubernetes, confirm the secret is mounted into the pod (check volumes/volumeMounts) and the container has read access","Copy the CA bundle to the client host if running the CLI outside the cluster"],"exampleFix":"// before\nconfig, err := tls.GetClientTLSConfig(\"\", \"\", \"/etc/argo/ca.crt\", false)\n// after (verify file exists first)\nif _, err := os.Stat(\"/etc/argo/ca.crt\"); err != nil { /* fix path/mount */ }\nconfig, err := tls.GetClientTLSConfig(\"\", \"\", \"/etc/argo/server-ca.crt\", false)","handlingStrategy":"validation","validationCode":"func caReadable(path string) error {\n    if path == \"\" { return nil }\n    fi, err := os.Stat(path)\n    if err != nil { return fmt.Errorf(\"CA file %q: %w\", path, err) }\n    if fi.Mode()&0o400 == 0 { return fmt.Errorf(\"CA file %q not readable\", path) }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"var pathErr *fs.PathError\nconfig, err := tls.GetClientTLSConfig(cert, key, caCert, insecure)\nif err != nil && errors.As(err, &pathErr) {\n    return fmt.Errorf(\"CA path %q unusable, check mount/permissions: %w\", caCert, err)\n}","preventionTips":["Verify the CA path exists inside the same container that runs the client","Check secret volumeMounts when running in Kubernetes","Use absolute paths; don't rely on host paths that differ in containers","Test with `kubectl exec` that the file is readable by the process user"],"tags":["tls","file-not-found","ca-certificate","filesystem"],"backgroundTag":"ca-cert-file-not-found","analyzedSha":"35bff19146f5a6ada77468c431f2624bd577e373","analyzedAt":"2026-09-03T19:34:35.908Z","contentChangedAt":"2026-09-03T19:34:35.908Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}