{"record":{"id":"d597d14cdc45ac98","repo":"hyperledger/fabric","slug":"failed-parsing-request","errorCode":null,"errorMessage":"failed parsing request","messagePattern":"failed parsing request","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"discovery/service.go","lineNumber":239,"sourceCode":"\t\t\t\tcontinue\n\t\t\t}\n\t\t\tpeersForCurrentOrg[string(id.PKIId)] = &discovery.Peer{\n\t\t\t\tIdentity:       id.Identity,\n\t\t\t\tMembershipInfo: aliveInfo.Envelope,\n\t\t\t}\n\t\t}\n\t}\n\treturn peersByOrg\n}\n\n// validateStructure validates that the request contains all the needed fields and that they are computed correctly\nfunc validateStructure(ctx context.Context, request *discovery.SignedRequest, tlsEnabled bool, certHashFromContext certHashExtractor) (*discovery.Request, error) {\n\tif request == nil {\n\t\treturn nil, errors.New(\"nil request\")\n\t}\n\treq, err := protoext.SignedRequestToRequest(request)\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"failed parsing request\")\n\t}\n\tif req.Authentication == nil {\n\t\treturn nil, errors.New(\"access denied, no authentication info in request\")\n\t}\n\tif len(req.Authentication.ClientIdentity) == 0 {\n\t\treturn nil, errors.New(\"access denied, client identity wasn't supplied\")\n\t}\n\tif !tlsEnabled {\n\t\treturn req, nil\n\t}\n\tcomputedHash := certHashFromContext(ctx)\n\tif len(computedHash) == 0 {\n\t\treturn nil, errors.New(\"client didn't send a TLS certificate\")\n\t}\n\tif !bytes.Equal(computedHash, req.Authentication.ClientTlsCertHash) {\n\t\tclaimed := hex.EncodeToString(req.Authentication.ClientTlsCertHash)\n\t\tlogger.Warningf(\"client claimed TLS hash %s doesn't match computed TLS hash from gRPC stream %s\", claimed, hex.EncodeToString(computedHash))\n\t\treturn nil, errors.New(\"client claimed TLS hash doesn't match computed TLS hash from gRPC stream\")","sourceCodeStart":221,"sourceCodeEnd":257,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/discovery/service.go#L221-L257","documentation":"This error wraps any failure from protoext.SignedRequestToRequest while converting the signed protobuf payload into a *discovery.Request. It indicates the request bytes are not a parseable SignedRequest — malformed payload, empty payload, or invalid protobuf encoding — so the service cannot proceed to authentication.","triggerScenarios":"A client sends a SignedRequest whose payload fails protobuf unmarshaling: empty payload bytes, corrupted/truncated serialization, or a payload that is not the expected discovery SignedRequest message type.","commonSituations":"Hand-crafting the request bytes instead of using the SDK; mixing incompatible Fabric SDK/proto versions so wire formats differ; network middleware mangling the body; sending a different protobuf message to the discovery endpoint.","solutions":["Build the request with the official discovery client/SDK (dis.NewRequest ... Sign) instead of manually serializing","Check the server log for the wrapped root error detailing why SignedRequestToRequest failed","Ensure SDK and Fabric peer proto versions are compatible (fabric-protos mismatch)","Regenerate/rebuild generated protobuf code if you customized the client serialization","Capture the outgoing payload and verify it decodes as a discovery.SignedRequest with protoc"],"exampleFix":"// before\npayload := []byte(\"manual request\")\nreq := &discovery.SignedRequest{Payload: payload} // not valid protobuf\n// after\nr := discovery.NewRequest().AddQueryToConfigQuery()\nr.Authentication.ClientIdentity = identity\npayload, err := proto.Marshal(r.ToRequest()) // serialize the real message\nif err != nil { return err }\nreq := &discovery.SignedRequest{Payload: payload, Signature: sig}","handlingStrategy":"validation","validationCode":"payload := signedReq.GetPayload()\nif len(payload) == 0 {\n    return errors.New(\"discovery: request payload empty; will fail server-side parsing\")\n}\nvar chk discovery.Request\nif err := proto.Unmarshal(payload, &chk); err != nil {\n    return fmt.Errorf(\"discovery: payload is not a valid Request: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"resp, err := client.Send(ctx, signedReq)\nif err != nil {\n    if strings.Contains(err.Error(), \"failed parsing request\") {\n        // rebuild request from scratch and retry once\n        return rebuildAndSend(ctx)\n    }\n    return nil, err\n}","preventionTips":["Serialize with the same fabric-protos version used by the peer","Never hand-build request bytes; use discovery.NewRequest() and Sign","Keep SDK and peer releases in sync","Add a smoke test that sends a real signed request in CI"],"tags":["hyperledger-fabric","discovery-service","protobuf","deserialization"],"backgroundTag":"request-parse-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"}