{"record":{"id":"411f6ad9f4d6bb2d","repo":"snail007/goproxy","slug":"failed-to-parse-root-certificate","errorCode":null,"errorMessage":"failed to parse root certificate","messagePattern":"failed to parse root certificate","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"utils/functions.go","lineNumber":134,"sourceCode":"\tif err != nil {\n\t\treturn\n\t}\n\t_conn, err := net.DialTimeout(\"tcp\", fmt.Sprintf(\"%s:%d\", host, port), time.Duration(timeout)*time.Millisecond)\n\tif err != nil {\n\t\treturn\n\t}\n\treturn *tls.Client(_conn, conf), err\n}\nfunc getRequestTlsConfig(certBytes, keyBytes []byte) (conf *tls.Config, err error) {\n\tvar cert tls.Certificate\n\tcert, err = tls.X509KeyPair(certBytes, keyBytes)\n\tif err != nil {\n\t\treturn\n\t}\n\tserverCertPool := x509.NewCertPool()\n\tok := serverCertPool.AppendCertsFromPEM(certBytes)\n\tif !ok {\n\t\terr = errors.New(\"failed to parse root certificate\")\n\t}\n\tconf = &tls.Config{\n\t\tRootCAs:            serverCertPool,\n\t\tCertificates:       []tls.Certificate{cert},\n\t\tServerName:         \"proxy\",\n\t\tInsecureSkipVerify: false,\n\t}\n\treturn\n}\n\nfunc ConnectHost(hostAndPort string, timeout int) (conn net.Conn, err error) {\n\tconn, err = net.DialTimeout(\"tcp\", hostAndPort, time.Duration(timeout)*time.Millisecond)\n\treturn\n}\nfunc ListenTls(ip string, port int, certBytes, keyBytes []byte) (ln *net.Listener, err error) {\n\tvar cert tls.Certificate\n\tcert, err = tls.X509KeyPair(certBytes, keyBytes)\n\tif err != nil {","sourceCodeStart":116,"sourceCodeEnd":152,"githubUrl":"https://github.com/snail007/goproxy/blob/e6d6a821db80e7f47ee6e981a144984e1d4ddb3d/utils/functions.go#L116-L152","documentation":"getRequestTlsConfig builds a tls.Config for an outgoing TLS connection to the proxy parent. After loading PEM bytes it calls x509 CertPool.AppendCertsFromPEM, and this error is thrown when the returned ok flag is false, i.e. none of the supplied bytes could be parsed as a PEM-encoded certificate. The library requires a valid root/CA certificate file to authenticate the proxy, so it aborts instead of silently skipping verification (InsecureSkipVerify is false).","triggerScenarios":"The certificate file configured for the TLS parent points to a missing, empty, non-PEM, or corrupt file; AppendCertsFromPEM returns false when certBytes contains no parseable PEM CERTIFICATE blocks, so getRequestTlsConfig constructs the error and TlsConnect fails.","commonSituations":"Config pointing root CA path at the wrong file or a private key instead of a certificate; certificate generated in DER format instead of PEM; file truncated by a failed copy/mount; using an expired or malformed cert generated by a broken tooling pipeline.","solutions":["Regenerate or re-export the CA certificate in PEM format (openssl x509 -in cert.der -out ca.pem -outform PEM) and point the config at that file","Verify the file actually contains PEM blocks: head the file and confirm '-----BEGIN CERTIFICATE-----' lines exist and it is not empty or a key","Check the config path for typos and that the process has read permission on the file","As a last resort for testing only, run with verification skipped (insecure mode), but never in production"],"exampleFix":"// before (certBytes from a DER file -> AppendCertsFromPEM returns false)\nok := serverCertPool.AppendCertsFromPEM(certBytes)\n// after: ensure the file is PEM on disk\n// openssl x509 -in ca.crt -out ca.pem -outform PEM\n// then start with ca.pem configured\nok := serverCertPool.AppendCertsFromPEM(certBytes) // ok == true","handlingStrategy":"validation","validationCode":"func validPEM(path string) error {\n    b, err := os.ReadFile(path)\n    if err != nil { return err }\n    if !bytes.Contains(b, []byte(\"-----BEGIN CERTIFICATE-----\")) {\n        return fmt.Errorf(\"%s is not a PEM certificate\", path)\n    }\n    return nil\n}\n// call before starting the service: validPEM(cfg.CertPath)","typeGuard":null,"tryCatchPattern":"if err := startService(cfg); err != nil {\n    if strings.Contains(err.Error(), \"failed to parse root certificate\") {\n        // surface config guidance: check CA file is PEM\n    }\n}","preventionTips":["Always distribute CA certs in PEM format (BEGIN CERTIFICATE blocks)","Validate cert files at deploy time (openssl x509 -in ca.pem -noout) before launch","Use absolute, permission-checked paths for cert config","Regenerate certs with a single scripted pipeline to avoid format drift"],"tags":["tls","certificate","pem","x509"],"backgroundTag":"tls-certificate-parse-failed","analyzedSha":"e6d6a821db80e7f47ee6e981a144984e1d4ddb3d","analyzedAt":"2026-09-03T15:32:42.750Z","contentChangedAt":"2026-09-03T15:32:42.750Z","schemaVersion":2},"datasetVersion":"2026-09-11T00:17:11.886Z"}