{"record":{"id":"28a10cf891039e84","repo":"hyperledger/fabric","slug":"failed-to-add-ca-file-pem-to-cert-pool","errorCode":null,"errorMessage":"failed to add ca-file PEM to cert pool","messagePattern":"failed to add ca-file PEM to cert pool","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/osnadmin/main.go","lineNumber":96,"sourceCode":"\t//\n\t// flag validation\n\t//\n\tvar (\n\t\tosnURL        string\n\t\tcaCertPool    *x509.CertPool\n\t\ttlsClientCert tls.Certificate\n\t)\n\t// TLS enabled\n\tif *caFile != \"\" {\n\t\tosnURL = fmt.Sprintf(\"https://%s\", *orderer)\n\t\tvar err error\n\t\tcaCertPool = x509.NewCertPool()\n\t\tcaFilePEM, err := os.ReadFile(*caFile)\n\t\tif err != nil {\n\t\t\treturn \"\", 1, fmt.Errorf(\"reading orderer CA certificate: %s\", err)\n\t\t}\n\t\tif !caCertPool.AppendCertsFromPEM(caFilePEM) {\n\t\t\treturn \"\", 1, errors.New(\"failed to add ca-file PEM to cert pool\")\n\t\t}\n\n\t\ttlsClientCert, err = tls.LoadX509KeyPair(*clientCert, *clientKey)\n\t\tif err != nil {\n\t\t\treturn \"\", 1, fmt.Errorf(\"loading client cert/key pair: %s\", err)\n\t\t}\n\t} else { // TLS disabled\n\t\tosnURL = fmt.Sprintf(\"http://%s\", *orderer)\n\t}\n\n\tvar marshaledConfigBlock []byte\n\tif *configBlockPath != \"\" {\n\t\tmarshaledConfigBlock, err = os.ReadFile(*configBlockPath)\n\t\tif err != nil {\n\t\t\treturn \"\", 1, fmt.Errorf(\"reading config block: %s\", err)\n\t\t}\n\n\t\terr = validateBlockChannelID(marshaledConfigBlock, *joinChannelID)","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/cmd/osnadmin/main.go#L78-L114","documentation":"After reading the --ca-file PEM bytes, osnadmin calls AppendCertsFromPEM to add them to an x509 cert pool. If the bytes contain no valid PEM-encoded certificates, the call returns false and this error is returned. It means the file was readable but is not a parseable PEM certificate.","triggerScenarios":"--ca-file pointing to a private key, an empty file, a DER/binary cert (not PEM), a config file by mistake, or a PEM bundle with only invalid/truncated blocks.","commonSituations":"Passing the TLS private key or the client cert instead of the CA cert; certs generated with wrong encoding; file corrupted by copy-paste or base64 left encoded; empty mounted secret.","solutions":["Verify the file contains a '-----BEGIN CERTIFICATE-----' block: head the file.","Point --ca-file at the orderer's CA certificate (e.g. tlsca cert), not a key or client cert.","If the cert is DER, convert it: openssl x509 -inform der -in cert.der -out ca.crt.","Check file size — an empty or truncated file must be re-exported from the orderer's MSP/tls directory."],"exampleFix":"// before (wrong file — private key)\nosnadmin channel join ... --ca-file /etc/fabric/tls/server.key\n// after (correct CA cert)\nosnadmin channel join ... --ca-file /etc/fabric/tls/ca.crt","handlingStrategy":"validation","validationCode":"pem, err := os.ReadFile(caFile)\nif err != nil { log.Fatal(err) }\npool := x509.NewCertPool()\nif !pool.AppendCertsFromPEM(pem) {\n    log.Fatalf(\"%s does not contain a valid PEM certificate\", caFile)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Confirm the file starts with -----BEGIN CERTIFICATE-----","Pass the orderer TLS CA cert, never a key or client cert","Convert DER certs to PEM with openssl before use","Check mounted secrets are non-empty"],"tags":["tls","osnadmin","pem","certificate"],"backgroundTag":"invalid-pem-certificate","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}