{"record":{"id":"2057b52a6f8b3c8e","repo":"t8y2/dbx","slug":"pem-truststore-contains-no-certificates","errorCode":null,"errorMessage":"PEM truststore contains no certificates","messagePattern":"PEM truststore contains no certificates","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agents/drivers/argo-go/zookeeper_tls.go","lineNumber":224,"sourceCode":"func parsePEMCertificates(contents []byte) ([]*x509.Certificate, error) {\n\tvar certificates []*x509.Certificate\n\tfor len(contents) > 0 {\n\t\tblock, rest := pem.Decode(contents)\n\t\tif block == nil {\n\t\t\tbreak\n\t\t}\n\t\tcontents = rest\n\t\tif block.Type != \"CERTIFICATE\" {\n\t\t\tcontinue\n\t\t}\n\t\tcertificate, err := x509.ParseCertificate(block.Bytes)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tcertificates = append(certificates, certificate)\n\t}\n\tif len(certificates) == 0 {\n\t\treturn nil, errors.New(\"PEM truststore contains no certificates\")\n\t}\n\treturn certificates, nil\n}\n\nfunc parsePrivateKey(contents []byte) (any, error) {\n\tif value, err := x509.ParsePKCS8PrivateKey(contents); err == nil {\n\t\treturn value, nil\n\t}\n\tif value, err := x509.ParsePKCS1PrivateKey(contents); err == nil {\n\t\treturn value, nil\n\t}\n\tif value, err := x509.ParseECPrivateKey(contents); err == nil {\n\t\treturn value, nil\n\t}\n\treturn nil, errors.New(\"unsupported private key encoding\")\n}\n","sourceCodeStart":206,"sourceCodeEnd":241,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/agents/drivers/argo-go/zookeeper_tls.go#L206-L241","documentation":"parsePEMCertificates decodes a PEM truststore into x509 certificates. If the PEM data yields zero certificates, it returns this error because an empty truststore cannot be used for TLS server verification. Invoked by loadTrustStore when the store type is PEM.","triggerScenarios":"buildTLSConfig/buildZooKeeperTLSConfig given a truststorePath whose file contains no CERTIFICATE PEM blocks — an empty file, a file with only PRIVATE KEY blocks, or binary/DER content mislabeled as .pem.","commonSituations":"Config var pointing to a path that exists but is empty (e.g. a mounted Kubernetes secret key not set); pasting a private key instead of the CA cert; downloading a cert that came as DER; concatenated bundle lost during secret templating.","solutions":["Verify the file contains '-----BEGIN CERTIFICATE-----' blocks: grep -c 'BEGIN CERTIFICATE' truststore.pem","Convert DER certs to PEM if needed: openssl x509 -inform der -in ca.crt -out ca.pem","Check the mounted secret/env var actually contains the CA certificate text, not an empty value","Ensure you pass the CA/public cert, not the private key PEM"],"exampleFix":"// before: truststore.pem contains '-----BEGIN PRIVATE KEY-----' only\n// after: export CA to PEM\n# openssl x509 -inform der -in ca.der -out truststore.pem","handlingStrategy":"validation","validationCode":"pemBytes, err := os.ReadFile(truststorePath)\nif err != nil { return err }\nif !bytes.Contains(pemBytes, []byte(\"-----BEGIN CERTIFICATE-----\")) {\n    return fmt.Errorf(\"%s contains no PEM certificates\", truststorePath)\n}","typeGuard":null,"tryCatchPattern":"certs, err := parsePEMCertificates(data)\nif err != nil && strings.Contains(err.Error(), \"PEM truststore contains no certificates\") {\n    // surface: check secret mount / file contents\n}","preventionTips":["Check file size and 'BEGIN CERTIFICATE' presence at startup, not only on first TLS handshake","Ensure Kubernetes secrets mount the CA cert key, not an empty template value","Convert DER certs to PEM before bundling"],"tags":["tls","pem","truststore","certificates","zookeeper"],"backgroundTag":"empty-truststore","analyzedSha":"c0390bff16418b651f4728520d99adf8ce48829a","analyzedAt":"2026-09-05T23:05:10.900Z","contentChangedAt":"2026-09-05T23:05:10.900Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}