{"record":{"id":"d26472404c23dcc6","repo":"hyperledger/fabric","slug":"failed-to-marshal-channel-metadata","errorCode":null,"errorMessage":"failed to marshal channel metadata","messagePattern":"failed to marshal channel metadata","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/ledger/kvledger/txmgmt/statedb/statecouchdb/couchdoc_conv.go","lineNumber":233,"sourceCode":"\t\treturn nil, err\n\t}\n\treturn &couchDoc{jsonValue: savepointDocJSON, attachments: nil}, nil\n}\n\nfunc decodeSavepoint(couchDoc *couchDoc) (*version.Height, error) {\n\tsavepointDoc := &couchSavepointData{}\n\tif err := json.Unmarshal(couchDoc.jsonValue, &savepointDoc); err != nil {\n\t\terr = errors.Wrap(err, \"failed to unmarshal savepoint data\")\n\t\tlogger.Errorf(\"%+v\", err)\n\t\treturn nil, err\n\t}\n\treturn &version.Height{BlockNum: savepointDoc.BlockNum, TxNum: savepointDoc.TxNum}, nil\n}\n\nfunc encodeChannelMetadata(metadataDoc *channelMetadata) (*couchDoc, error) {\n\tmetadataJSON, err := json.Marshal(metadataDoc)\n\tif err != nil {\n\t\terr = errors.Wrap(err, \"failed to marshal channel metadata\")\n\t\tlogger.Errorf(\"%+v\", err)\n\t\treturn nil, err\n\t}\n\treturn &couchDoc{jsonValue: metadataJSON, attachments: nil}, nil\n}\n\nfunc decodeChannelMetadata(couchDoc *couchDoc) (*channelMetadata, error) {\n\tmetadataDoc := &channelMetadata{}\n\tif err := json.Unmarshal(couchDoc.jsonValue, &metadataDoc); err != nil {\n\t\terr = errors.Wrap(err, \"failed to unmarshal channel metadata\")\n\t\tlogger.Errorf(\"%+v\", err)\n\t\treturn nil, err\n\t}\n\treturn metadataDoc, nil\n}\n\ntype dataformatInfo struct {\n\tVersion string `json:\"Version\"`","sourceCodeStart":215,"sourceCodeEnd":251,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/ledger/kvledger/txmgmt/statedb/statecouchdb/couchdoc_conv.go#L215-L251","documentation":"encodeChannelMetadata serializes the channelMetadata document (ledger metadata persisted in the CouchDB state database) to JSON. A failure is wrapped with 'failed to marshal channel metadata' and writeChannelMetadata aborts. As with the savepoint, this marshal of a simple struct should never fail in stock Fabric.","triggerScenarios":"writeChannelMetadata calls encodeChannelMetadata and json.Marshal fails on the channelMetadata struct being persisted.","commonSituations":"Custom modifications to channelMetadata adding non-serializable fields; corrupt toolchain or dependency substitutions.","solutions":["Check the wrapped cause in the Errorf log output","Keep channelMetadata limited to JSON-serializable fields (strings, numbers)","Rebuild with unmodified Fabric sources and retry the ledger operation"],"exampleFix":"// before\ntype channelMetadata struct {\n    DataFormatVersion string\n    Hooks map[string]func() // not serializable\n}\n// after\ntype channelMetadata struct {\n    DataFormatVersion string\n}","handlingStrategy":"try-catch","validationCode":"if _, err := json.Marshal(metadataDoc); err != nil {\n    return fmt.Errorf(\"channel metadata not serializable: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"doc, err := encodeChannelMetadata(md)\nif err != nil {\n    logger.Errorf(\"channel metadata encode failed: %+v\", err)\n    return nil, err\n}","preventionTips":["Keep channelMetadata fields JSON-serializable","Avoid custom forks that alter internal metadata structs"],"tags":["json","marshalling","channel-metadata","fabric-ledger"],"backgroundTag":"json-marshalling-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"}