{"record":{"id":"a740e64e2cee24f7","repo":"hyperledger/fabric","slug":"s-tls-certificate-has-invalid-asn1-structure-s","errorCode":null,"errorMessage":"%s TLS certificate has invalid ASN1 structure %s","messagePattern":"(.+?) TLS certificate has invalid ASN1 structure (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"orderer/consensus/etcdraft/util.go","lineNumber":266,"sourceCode":"\t\t}\n\t}\n\n\tif err := MetadataHasDuplication(metadata); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc parseCertificateFromBytes(cert []byte) (*x509.Certificate, error) {\n\tpemBlock, _ := pem.Decode(cert)\n\tif pemBlock == nil {\n\t\treturn &x509.Certificate{}, errors.Errorf(\"no PEM data found in cert[% x]\", cert)\n\t}\n\n\tcertificate, err := x509.ParseCertificate(pemBlock.Bytes)\n\tif err != nil {\n\t\treturn nil, errors.Errorf(\"%s TLS certificate has invalid ASN1 structure %s\", err, string(pemBlock.Bytes))\n\t}\n\n\treturn certificate, nil\n}\n\nfunc parseCertificateListFromBytes(certs [][]byte) ([]*x509.Certificate, error) {\n\tvar certificateList []*x509.Certificate\n\n\tfor _, cert := range certs {\n\t\tcertificate, err := parseCertificateFromBytes(cert)\n\t\tif err != nil {\n\t\t\treturn certificateList, err\n\t\t}\n\n\t\tcertificateList = append(certificateList, certificate)\n\t}\n\n\treturn certificateList, nil","sourceCodeStart":248,"sourceCodeEnd":284,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/consensus/etcdraft/util.go#L248-L284","documentation":"parseCertificateFromBytes decodes a PEM-encoded TLS certificate and calls x509.ParseCertificate. When the PEM block exists but its DER bytes are not a valid ASN.1 DER certificate, the Go standard library parse fails and Hyperledger Fabric wraps that err (plus the raw PEM bytes) into an errors.Errorf. This signals malformed certificate data supplied via channel config, not a network or trust issue.","triggerScenarios":"etcdraft channel config update where a consenter's client_tls_cert or server_tls_cert is not a valid DER-encoded X.509 certificate (e.g. a key file, empty/garbage PEM payload, or truncated base64) — raised via validateConsenterTLSCerts, parseCertificateListFromBytes, or TestVerifyConfigMetadata paths such as VerifyConfigMetadata/ValidateConsensusMetadata.","commonSituations":"Ops paste the node's TLS private key instead of the certificate into configtx.yaml; the cert file was copied with corrupted/missing lines; an intermediate tool re-encoded the PEM incorrectly; a generated cert was replaced with a CSR or a PKCS#12 blob.","solutions":["Regenerate or re-export the certificate as a valid PEM/DER X.509 cert (openssl x509 -in cert.pem -text -noout must succeed) and re-run configtxgen","Confirm the field points to the certificate, not the private key (-----BEGIN CERTIFICATE----- vs -----BEGIN PRIVATE KEY-----)","Decode the failing bytes from the wrapped message and inspect them; fix base64 corruption/truncation","If certs come from an MSP folder, ensure tls/ca.crt and tlscacerts files are intact and correctly mounted"],"exampleFix":"// before: key mistakenly used as cert in configtx.yaml\nclient_tls_cert: \"LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0t...\"\n// after: base64 of a real CERTIFICATE PEM\nclient_tls_cert: \"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0t...\"","handlingStrategy":"validation","validationCode":"// validate before placing into config / calling the API\nfunc validateTLSCertBytes(certPEM []byte) error {\n    block, _ := pem.Decode(certPEM)\n    if block == nil {\n        return fmt.Errorf(\"no PEM data\")\n    }\n    if _, err := x509.ParseCertificate(block.Bytes); err != nil {\n        return fmt.Errorf(\"invalid ASN1 cert: %w\", err)\n    }\n    return nil\n}\n// run: validateTLSCertBytes(tlsCertBytes) before channel config update","typeGuard":"func isPEMCertificate(b []byte) bool {\n    block, _ := pem.Decode(b)\n    return block != nil && block.Type == \"CERTIFICATE\"\n}","tryCatchPattern":null,"preventionTips":["Always verify with `openssl x509 -in cert.pem -text -noout` before base64-encoding into configtx.yaml","Never confuse .crt/.pem cert files with .key private key files when filling tls cert fields","Keep certificate fields generated by tooling (cryptogen/fabric-ca scripts), not hand-edited","Add CI linting that decodes every PEM field of configtx.yaml"],"tags":["x509","tls","certificate-parsing","hyperledger-fabric"],"backgroundTag":"invalid-asn1-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"}