{"record":{"id":"de26b52cf726b2dd","repo":"hyperledger/fabric","slug":"received-nil-proposal-response-de26b5","errorCode":null,"errorMessage":"received nil proposal response","messagePattern":"received nil proposal response","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/peer/lifecycle/chaincode/querycommitted.go","lineNumber":129,"sourceCode":"\t}\n\n\tproposal, err := c.createProposal()\n\tif err != nil {\n\t\treturn errors.WithMessage(err, \"failed to create proposal\")\n\t}\n\n\tsignedProposal, err := signProposal(proposal, c.Signer)\n\tif err != nil {\n\t\treturn errors.WithMessage(err, \"failed to create signed proposal\")\n\t}\n\n\tproposalResponse, err := c.EndorserClient.ProcessProposal(context.Background(), signedProposal)\n\tif err != nil {\n\t\treturn errors.WithMessage(err, \"failed to endorse proposal\")\n\t}\n\n\tif proposalResponse == nil {\n\t\treturn errors.New(\"received nil proposal response\")\n\t}\n\n\tif proposalResponse.Response == nil {\n\t\treturn errors.New(\"received proposal response with nil response\")\n\t}\n\n\tif proposalResponse.Response.Status != int32(cb.Status_SUCCESS) {\n\t\treturn errors.Errorf(\"query failed with status: %d - %s\", proposalResponse.Response.Status, proposalResponse.Response.Message)\n\t}\n\n\tif strings.ToLower(c.Input.OutputFormat) == \"json\" {\n\t\treturn c.printResponseAsJSON(proposalResponse)\n\t}\n\treturn c.printResponse(proposalResponse)\n}\n\nfunc (c *CommittedQuerier) printResponseAsJSON(proposalResponse *pb.ProposalResponse) error {\n\tif c.Input.Name != \"\" {","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/internal/peer/lifecycle/chaincode/querycommitted.go#L111-L147","documentation":"CommittedQuerier.Query checks that the endorser returned a non-nil proposal response after ProcessProposal succeeds. A nil response despite a nil error would violate the gRPC contract and indicates a broken/unexpected endorser client implementation, so the client defends against it explicitly.","triggerScenarios":"Calling Query (peer lifecycle chaincode querycommitted) with an EndorserClient whose ProcessProposal returns (nil, nil) — e.g. a faulty mock, misconfigured gRPC interceptor, or custom transport returning an empty result.","commonSituations":"Testing with stubbed endorser clients that return nil without an error, network middlewares/proxies that swallow responses, or gRPC misconfiguration where the connection reports success but no message arrives.","solutions":["Check network/TLS connectivity to the peer; re-run the command to rule out a transient empty response","If using a custom or proxying endorser client, fix it to return an error when no response is produced","Inspect gRPC interceptor/proxy configuration that might drop the response message","Verify you are connecting to a genuine Fabric peer endorser endpoint"],"exampleFix":"// before: assuming response is always present\nproposalResponse, err := c.EndorserClient.ProcessProposal(context.Background(), signedProposal)\nif err != nil {\n\treturn errors.WithMessage(err, \"failed to endorse proposal\")\n}\n// after (client-side defensive check)\nproposalResponse, err := c.EndorserClient.ProcessProposal(context.Background(), signedProposal)\nif err != nil {\n\treturn errors.WithMessage(err, \"failed to endorse proposal\")\n}\nif proposalResponse == nil || proposalResponse.Response == nil {\n\treturn errors.New(\"endorser returned nil or empty proposal response\")\n}","handlingStrategy":"type-guard","validationCode":"if proposalResponse == nil || proposalResponse.Response == nil {\n\treturn errors.New(\"endorser returned no usable proposal response\")\n}","typeGuard":"func hasUsableResponse(resp *pb.ProposalResponse) bool {\n\treturn resp != nil && resp.Response != nil && len(resp.Response.Payload) > 0\n}","tryCatchPattern":"proposalResponse, err := endorser.ProcessProposal(ctx, signedProposal)\nif err != nil {\n\treturn errors.WithMessage(err, \"failed to endorse proposal\")\n}\nif !hasUsableResponse(proposalResponse) {\n\treturn errors.New(\"received nil or empty proposal response\")\n}","preventionTips":["Always nil-check both proposalResponse and proposalResponse.Response before use","Use the official Fabric EndorserClient, not stubs, in production paths","Audit gRPC interceptors/proxies that could swallow response messages","Retry transient empty responses with backoff before failing permanently"],"tags":["hyperledger-fabric","grpc","endorser","nil-response"],"backgroundTag":"nil-response-from-rpc","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"}