{"record":{"id":"9132fa108b16163a","repo":"hyperledger/fabric","slug":"marshal-failed-proto-marshal-called-with-nil","errorCode":null,"errorMessage":"marshal failed: proto: Marshal called with nil","messagePattern":"marshal failed: proto: Marshal called with nil","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/chaincode/handler.go","lineNumber":877,"sourceCode":"\t\t}\n\t\trangeIter, err = txContext.TXSimulator.GetStateRangeScanIteratorWithPagination(namespaceID,\n\t\t\tstartKey, getStateByRange.EndKey, metadata.PageSize)\n\t} else {\n\t\trangeIter, err = txContext.TXSimulator.GetStateRangeScanIterator(namespaceID, getStateByRange.StartKey, getStateByRange.EndKey)\n\t}\n\tif err != nil {\n\t\treturn nil, errors.WithStack(err)\n\t}\n\ttxContext.InitializeQueryContext(iterID, rangeIter)\n\n\tpayload, err := h.QueryResponseBuilder.BuildQueryResponse(txContext, rangeIter, iterID, isPaginated, totalReturnLimit)\n\tif err != nil {\n\t\ttxContext.CleanupQueryContext(iterID)\n\t\treturn nil, errors.WithStack(err)\n\t}\n\tif payload == nil {\n\t\ttxContext.CleanupQueryContext(iterID)\n\t\treturn nil, errors.New(\"marshal failed: proto: Marshal called with nil\")\n\t}\n\n\tpayloadBytes, err := proto.Marshal(payload)\n\tif err != nil {\n\t\ttxContext.CleanupQueryContext(iterID)\n\t\treturn nil, errors.Wrap(err, \"marshal failed\")\n\t}\n\n\tchaincodeLogger.Debugf(\"Got keys and values. Sending %s\", pb.ChaincodeMessage_RESPONSE)\n\treturn &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Payload: payloadBytes, Txid: msg.Txid, ChannelId: msg.ChannelId}, nil\n}\n\n// Handles query to ledger for query state next\nfunc (h *Handler) HandleQueryStateNext(msg *pb.ChaincodeMessage, txContext *TransactionContext) (*pb.ChaincodeMessage, error) {\n\tqueryStateNext := &pb.QueryStateNext{}\n\terr := proto.Unmarshal(msg.Payload, queryStateNext)\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"unmarshal failed\")","sourceCodeStart":859,"sourceCodeEnd":895,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/chaincode/handler.go#L859-L895","documentation":"In the query-response path, after collecting the query result, the handler sanity-checks that the payload to return is non-nil before proto.Marshal. If getQueryResponseForIterator yields a nil payload, the peer returns an error literally 'marshal failed: proto: Marshal called with nil' and cleans up the query context. It guards against marshalling a nil protobuf message which would otherwise panic or produce a broken response.","triggerScenarios":"The internal query-response builder returns a nil protobuf payload for an iterator ID — e.g. the next-state result construction failed to produce a valid QueryResponse message while iterating range/query results.","commonSituations":"Peer-side iterator/query-context issues (expired or corrupted query context), ledger provider returning empty result structures, or Fabric bugs in specific versions around paginated queries.","solutions":["Upgrade Hyperledger Fabric to the latest patch release; this guard indicates an unexpected nil that upstream fixes have addressed.","Retry the range/query transaction; transient query-context issues may resolve.","Check for query-context expiry (totalQueryLimit / query timeout) and reduce result window size or use pagination.","Inspect peer logs around the query for the underlying ledger error that produced a nil payload."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":"func hasValidQueryPayload(payload interface{ Reset(); String() string; ProtoMessage() }) bool { return payload != nil && !reflect.ValueOf(payload).IsNil() }","tryCatchPattern":"iter, err := stub.GetStateByRange(start, end)\nif err != nil && strings.Contains(err.Error(), \"marshal failed\") {\n    // retry transaction once; if persistent, reduce query window / upgrade peer\n    return retryRangeQuery(start, end)\n}","preventionTips":["Keep peers on current Fabric patch releases.","Use pagination and bounded ranges to avoid long-lived query contexts.","Retry transient query failures; escalate persistent nil-payload errors to the Fabric project."],"tags":["hyperledger-fabric","protobuf","query-iterator","marshal"],"backgroundTag":"protobuf-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"}