{"record":{"id":"84c2a02a46e3410f","repo":"hyperledger/fabric","slug":"failed-marshaling-new-certificate","errorCode":null,"errorMessage":"failed marshaling new certificate","messagePattern":"failed marshaling new certificate","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/crypto/sanitize.go","lineNumber":82,"sourceCode":"\t// Else it's high-S, so shift it below half the order.\n\ts.Sub(curveOrderUsedByCryptoGen, s)\n\n\tvar newCert certificate\n\t_, err = asn1.Unmarshal(cert.Raw, &newCert)\n\tif err != nil {\n\t\treturn nil, errors.Wrapf(err, \"failed unmarshaling certificate\")\n\t}\n\n\tnewSig, err := utils.MarshalECDSASignature(r, s)\n\tif err != nil {\n\t\treturn nil, errors.Wrapf(err, \"failed marshaling ECDSA signature\")\n\t}\n\tnewCert.SignatureValue = asn1.BitString{Bytes: newSig, BitLength: len(newSig) * 8}\n\n\tnewCert.Raw = nil\n\tnewRaw, err := asn1.Marshal(newCert)\n\tif err != nil {\n\t\treturn nil, errors.Wrapf(err, \"failed marshaling new certificate\")\n\t}\n\n\tfinalPEM := pem.EncodeToMemory(&pem.Block{Type: \"CERTIFICATE\", Bytes: newRaw})\n\treturn finalPEM, nil\n}\n\ntype certificate struct {\n\tRaw                asn1.RawContent\n\tTBSCertificate     tbsCertificate\n\tSignatureAlgorithm pkix.AlgorithmIdentifier\n\tSignatureValue     asn1.BitString\n}\n\ntype tbsCertificate struct {\n\tRaw                asn1.RawContent\n\tVersion            int `asn1:\"optional,explicit,default:0,tag:0\"`\n\tSerialNumber       *big.Int\n\tSignatureAlgorithm pkix.AlgorithmIdentifier","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/common/crypto/sanitize.go#L64-L100","documentation":"After re-building the sanitized certificate struct, SanitizeX509Cert re-marshals it to ASN.1 DER (asn1.Marshal). Failure means the reconstructed certificate structure is not encodable, so the sanitized PEM cannot be produced.","triggerScenarios":"asn1.Marshal(newCert) fails after Raw is set to nil — e.g., the newCert struct contains fields the encoding/asn1 package cannot encode (unexpected field types, invalid BIT STRING, malformed extensions).","commonSituations":"Certificates with unusual/unexpected extension data or critical fields the generic asn1 struct cannot round-trip; very old or exotic CA-issued certs.","solutions":["Inspect the failing certificate's extensions (openssl x509 -text) for non-standard fields","Upgrade to a version where certificate sanitization uses x509 certificate re-serialization instead of generic asn1.Marshal","Bypass sanitization for this cert by issuing a fresh certificate from the CA"],"exampleFix":"// before\nnewCert.Raw = nil\nnewRaw, err := asn1.Marshal(newCert)\n// after\nif _, err := asn1.Marshal(newCert); err != nil {\n    return nil, fmt.Errorf(\"cannot sanitize cert %s: %w\", cert.Subject, err)\n}","handlingStrategy":"try-catch","validationCode":"if _, err := asn1.Marshal(newCert); err != nil {\n    return fmt.Errorf(\"cert not re-encodable, skip sanitization: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"pemBytes, err := crypto.SanitizeX509Cert(certPEM)\nif err != nil && strings.Contains(err.Error(), \"failed marshaling new certificate\") {\n    return nil, fmt.Errorf(\"certificate structure unsupported by sanitizer: %w\", err)\n}","preventionTips":["Avoid feeding certificates with exotic extensions to the sanitizer","Upgrade fabric versions where cert sanitization has been hardened","Fall back to using the original cert when sanitization fails and sanitization is only advisory"],"tags":["crypto","asn1","certificate"],"backgroundTag":"asn1-marshal-failed","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"}