{"record":{"id":"c29e274d31018cc7","repo":"cloudflare/cloudflared","slug":"parse-ca-certificate-s","errorCode":null,"errorMessage":"parse CA certificate %s","messagePattern":"parse CA certificate (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tlsconfig/origin_ca.go","lineNumber":86,"sourceCode":"\t}\n\n\tif !certPool.AppendCertsFromPEM(customOriginCA) {\n\t\treturn nil, fmt.Errorf(\"error appending custom CA to cert pool\")\n\t}\n\treturn certPool, nil\n}\n\nfunc CreateTunnelConfig(caCert string, serverName string) (*tls.Config, error) {\n\ttlsConfig := &tls.Config{ServerName: serverName}\n\tif caCert != \"\" {\n\t\tcaCertPEM, err := os.ReadFile(caCert) //nolint:gosec\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"read CA certificate %s: %w\", caCert, err)\n\t\t}\n\n\t\trootCAPool := x509.NewCertPool()\n\t\tif !rootCAPool.AppendCertsFromPEM(caCertPEM) {\n\t\t\treturn nil, fmt.Errorf(\"parse CA certificate %s\", caCert)\n\t\t}\n\t\ttlsConfig.RootCAs = rootCAPool\n\t}\n\n\tif tlsConfig.RootCAs == nil {\n\t\trootCAPool, err := x509.SystemCertPool()\n\t\tif err != nil {\n\t\t\treturn nil, errors.Wrap(err, \"unable to get x509 system cert pool\")\n\t\t}\n\t\tcfRootCA, err := GetCloudflareRootCA()\n\t\tif err != nil {\n\t\t\treturn nil, errors.Wrap(err, \"could not append Cloudflare Root CAs to cloudflared certificate pool\")\n\t\t}\n\t\tfor _, cert := range cfRootCA {\n\t\t\trootCAPool.AddCert(cert)\n\t\t}\n\t\ttlsConfig.RootCAs = rootCAPool\n\t}","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/cloudflare/cloudflared/blob/2253eeeb25a44a713a4b60b8ba1e1b3f377d1a0f/tlsconfig/origin_ca.go#L68-L104","documentation":"After successfully reading the CA file, CreateTunnelConfig feeds the PEM bytes to x509.CertPool.AppendCertsFromPEM. That function returns false when the bytes contain no parseable PEM certificate blocks (it does not return an error). Cloudflared surfaces this as \"parse CA certificate <path>\" to indicate the file was readable but its content is not a valid PEM-encoded certificate (or is an empty/garbage file).","triggerScenarios":"CreateTunnelConfig called with a caCert path whose contents are not PEM certificates: the file holds a DER/ binary certificate, a private key, a CSR, concatenated junk, an empty file, or PEM blocks of a non-CERTIFICATE type.","commonSituations":"Users download a certificate in DER format instead of PEM; they point the flag at a private key or the certificate chain of the wrong entity; the file was truncated by a failed download or contains only an intermediate without any CERTIFICATE blocks; editors saved the file with HTML error-page content.","solutions":["Inspect the file: it must contain blocks like `-----BEGIN CERTIFICATE-----`. Run `openssl x509 -in <path> -text -noout` to validate.","Convert DER to PEM if needed: `openssl x509 -inform der -in cert.der -out cert.pem`.","Verify you are pointing at the CA/roots bundle, not a private key or leaf certificate chain without CERTIFICATE PEM blocks.","Re-download or re-export the CA bundle in PEM format, or omit caCert to use the system pool plus Cloudflare roots."],"exampleFix":"// before: file contains DER, AppendCertsFromPEM fails\n// $ openssl x509 -inform der -in origin-ca.der -out origin-ca.pem\ntlsCfg, err := tlsconfig.CreateTunnelConfig(\"/etc/cloudflared/origin-ca.pem\", \"example.com\")","handlingStrategy":"validation","validationCode":"func isPEMCertFile(path string) error {\n\tb, err := os.ReadFile(path)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif !bytes.Contains(b, []byte(\"-----BEGIN CERTIFICATE-----\")) {\n\t\treturn fmt.Errorf(\"%s has no PEM CERTIFICATE blocks\", path)\n\t}\n\treturn nil\n}","typeGuard":null,"tryCatchPattern":"tlsCfg, err := tlsconfig.CreateTunnelConfig(caPath, serverName)\nif err != nil {\n\tif strings.HasPrefix(err.Error(), \"parse CA certificate\") {\n\t\tlog.Fatal().Msgf(\"%s is not a PEM certificate; convert with openssl x509 -inform der\", caPath)\n\t}\n\tlog.Fatal().Err(err).Msg(\"failed to build tunnel TLS config\")\n}","preventionTips":["Validate CA bundles with `openssl x509 -in <file> -text -noout` before deployment.","Always export certificates in PEM format, never DER.","Check downloaded files are not HTML error pages (common with curl on wrong URLs).","Point the CA flag at a root/CA bundle, not a private key or CSR."],"tags":["tls","certificate","pem","x509","configuration"],"backgroundTag":"invalid-config-value","analyzedSha":"2253eeeb25a44a713a4b60b8ba1e1b3f377d1a0f","analyzedAt":"2026-09-06T04:14:33.757Z","contentChangedAt":"2026-09-06T04:14:33.757Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}