{"record":{"id":"f6cf7535673a0305","repo":"hyperledger/fabric","slug":"proto-marshal-called-with-nil-f6cf75","errorCode":null,"errorMessage":"proto: Marshal called with nil","messagePattern":"proto: Marshal called with nil","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/peer/channel/fetch.go","lineNumber":97,"sourceCode":"\t\tlc, err2 := protoutil.GetLastConfigIndexFromBlock(iBlock)\n\t\tif err2 != nil {\n\t\t\treturn err2\n\t\t}\n\t\tlogger.Infof(\"Retrieving last config block: %d\", lc)\n\t\tblock, err = cf.DeliverClient.GetSpecifiedBlock(lc)\n\tdefault:\n\t\tnum, err2 := strconv.Atoi(args[0])\n\t\tif err2 != nil {\n\t\t\treturn fmt.Errorf(\"fetch target illegal: %s\", args[0])\n\t\t}\n\t\tblock, err = cf.DeliverClient.GetSpecifiedBlock(uint64(num))\n\t}\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif block == nil {\n\t\treturn errors.New(\"proto: Marshal called with nil\")\n\t}\n\tb, err := proto.Marshal(block)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tvar file string\n\tif len(args) == 1 {\n\t\tfile = channelID + \"_\" + args[0] + \".block\"\n\t} else {\n\t\tfile = args[1]\n\t}\n\n\tif err = os.WriteFile(file, b, 0o644); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/internal/peer/channel/fetch.go#L79-L115","documentation":"After fetching, the command sanity-checks that the delivered block is non-nil before proto.Marshal. A nil block would make the protobuf marshal panic ('proto: Marshal called with nil'), so fetch returns this error defensively when the deliver client returned success but no block.","triggerScenarios":"Deliver client returns no error but a nil block — e.g. a malformed/edge-case response from the orderer or an unexpected empty stream after GetSpecifiedBlock/GetNewestBlock.","commonSituations":"Orderer misbehaving or returning an empty response; proxy/load-balancer truncating the deliver stream; bugs in custom deliver implementations; race where the channel was deleted or reset.","solutions":["Retry the fetch; transient deliver issues often resolve.","Check orderer logs for errors serving the requested block.","Verify connectivity to the orderer without intermediaries (bypass proxies).","If persistent, ensure orderer and peer versions are compatible."],"exampleFix":"// not applicable — defensive internal check; fix is operational (retry/repair orderer connectivity)","handlingStrategy":"retry","validationCode":"// pre-check channel exists and orderer is healthy\npeer channel list\ncurl -s --cacert ca.pem https://orderer.example.com:7050/healthz 2>/dev/null || echo 'check orderer health endpoint'","typeGuard":null,"tryCatchPattern":"if err := cmd.Execute(); err != nil {\n    if strings.Contains(err.Error(), \"proto: Marshal called with nil\") {\n        // nil block from deliver; retry fetch, inspect orderer logs\n    }\n}","preventionTips":["Retry fetches on transient deliver failures.","Keep orderer and peer on compatible versions.","Avoid proxies/LBs that can truncate long-lived deliver streams.","Monitor orderer logs for block-serving errors."],"tags":["fabric","protobuf","deliver","nil-value"],"backgroundTag":"nil-value-marshall","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"}