{"record":{"id":"28d49972f3504f3e","repo":"hyperledger/fabric","slug":"parsing-tls-server-cert-of-s-d","errorCode":null,"errorMessage":"parsing tls server cert of %s:%d","messagePattern":"parsing tls server cert of (.+?):(.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"orderer/consensus/etcdraft/util.go","lineNumber":329,"sourceCode":"\t\tRoots:         tlsRoots,\n\t\tIntermediates: tlsIntermediates,\n\t\tKeyUsages: []x509.ExtKeyUsage{\n\t\t\tx509.ExtKeyUsageClientAuth,\n\t\t\tx509.ExtKeyUsageServerAuth,\n\t\t},\n\t}, nil\n}\n\n// validateConsenterTLSCerts decodes PEM cert, parses and validates it.\nfunc validateConsenterTLSCerts(c *etcdraft.Consenter, opts x509.VerifyOptions, ignoreExpiration bool) error {\n\tclientCert, err := parseCertificateFromBytes(c.GetClientTlsCert())\n\tif err != nil {\n\t\treturn errors.Wrapf(err, \"parsing tls client cert of %s:%d\", c.GetHost(), c.GetPort())\n\t}\n\n\tserverCert, err := parseCertificateFromBytes(c.GetServerTlsCert())\n\tif err != nil {\n\t\treturn errors.Wrapf(err, \"parsing tls server cert of %s:%d\", c.GetHost(), c.GetPort())\n\t}\n\n\tverify := func(certType string, cert *x509.Certificate, opts x509.VerifyOptions) error {\n\t\tif _, err := cert.Verify(opts); err != nil {\n\t\t\tif validationRes, ok := err.(x509.CertificateInvalidError); !ok || (!ignoreExpiration || validationRes.Reason != x509.Expired) {\n\t\t\t\treturn errors.Wrapf(err, \"verifying tls %s cert with serial number %d\", certType, cert.SerialNumber)\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}\n\n\tif err := verify(\"client\", clientCert, opts); err != nil {\n\t\treturn err\n\t}\n\tif err := verify(\"server\", serverCert, opts); err != nil {\n\t\treturn err\n\t}\n","sourceCodeStart":311,"sourceCodeEnd":347,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/consensus/etcdraft/util.go#L311-L347","documentation":"validateConsenterTLSCerts then parses the consenter's server TLS cert; failure is wrapped with 'parsing tls server cert of <host>:<port>'. As with the client cert, this indicates the server_tls_cert bytes in the etcdraft consenter config are not decodable PEM/DER X.509 data. The error surfaces during VerifyConfigMetadata or ValidateConsensusMetadata of the channel config.","triggerScenarios":"Channel config update for an etcdraft consenter whose GetServerTlsCert() is empty, non-PEM, or contains bytes that fail x509.ParseCertificate; the consenter is identified by host:port in the wrapped message.","commonSituations":"operator swapped the client and server cert fields; server_tls_cert contains the private key; cert pasted without proper base64 encoding; file truncated during copy into configtx.yaml.","solutions":["Set the consenter's server_tls_cert to the base64-encoded tls/server.crt (-----BEGIN CERTIFICATE-----) and update channel config","Verify the two cert fields aren't swapped: parse both with openssl x509 and compare with the node's actual TLS files","Check the cert file wasn't truncated (should contain header, body, footer lines) and re-encode with base64 -w0","Regenerate the node's TLS material and rebuild the config update transaction"],"exampleFix":"// before: base64 of key file\nserver_tls_cert: \"$(base64 orderer.example.com/tls/server.key)\"\n// after\nserver_tls_cert: \"$(base64 orderer.example.com/tls/server.crt)\"","handlingStrategy":"validation","validationCode":"// validate each consenter's server TLS cert before config update\nfor _, c := range metadata.Consenters {\n    if err := validateTLSCertBytes(c.ServerTlsCert); err != nil {\n        return fmt.Errorf(\"consenter %s:%d has invalid server tls cert: %w\", c.Host, c.Port, err)\n    }\n}","typeGuard":"func hasValidServerTLSCert(c *etcdraft.Consenter) bool {\n    block, _ := pem.Decode(c.GetServerTlsCert())\n    return block != nil && block.Type == \"CERTIFICATE\"\n}","tryCatchPattern":"if err := ValidateConsensusMetadata(m, l, nil); err != nil {\n    if strings.Contains(err.Error(), \"parsing tls server cert of\") {\n        return fmt.Errorf(\"a consenter's server_tls_cert is malformed: %w\", err)\n    }\n    return err\n}","preventionTips":["Fill server_tls_cert from the node's tls/server.crt only; never paste key material","Double-check client/server cert fields are not transposed in configtx.yaml","Verify cert PEM integrity (BEGIN/END lines intact) before encoding","Automate consenter cert population from the node's crypto dir instead of manual copy"],"tags":["x509","tls","etcdraft","consenter","hyperledger-fabric"],"backgroundTag":"invalid-consenter-tls-cert","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"}