{"record":{"id":"da11296c31c70701","repo":"hyperledger/fabric","slug":"no-signatures-for-nil-envelope","errorCode":null,"errorMessage":"No signatures for nil Envelope","messagePattern":"No signatures for nil Envelope","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"protoutil/signeddata.go","lineNumber":63,"sourceCode":"\t\t\treturn nil, err\n\t\t}\n\n\t\tresult[i] = &SignedData{\n\t\t\tData:      bytes.Join([][]byte{configSig.SignatureHeader, ce.ConfigUpdate}, nil),\n\t\t\tIdentity:  sigHeader.Creator,\n\t\t\tSignature: configSig.Signature,\n\t\t}\n\n\t}\n\n\treturn result, nil\n}\n\n// EnvelopeAsSignedData returns the signatures for the Envelope as SignedData\n// slice of length 1 or an error indicating why this was not possible.\nfunc EnvelopeAsSignedData(env *common.Envelope) ([]*SignedData, error) {\n\tif env == nil {\n\t\treturn nil, errors.New(\"No signatures for nil Envelope\")\n\t}\n\n\tpayload := &common.Payload{}\n\terr := proto.Unmarshal(env.Payload, payload)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif payload.Header == nil /* || payload.Header.SignatureHeader == nil */ {\n\t\treturn nil, errors.New(\"Missing Header\")\n\t}\n\n\tshdr := &common.SignatureHeader{}\n\terr = proto.Unmarshal(payload.Header.SignatureHeader, shdr)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"GetSignatureHeaderFromBytes failed, err %s\", err)\n\t}\n","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/protoutil/signeddata.go#L45-L81","documentation":"EnvelopeAsSignedData extracts the signature data from a common.Envelope: it unmarshals the payload and pairs env.Payload with env.Signature and the creator from the SignatureHeader. A nil Envelope has no signature to extract, so this error is returned immediately.","triggerScenarios":"Calling EnvelopeAsSignedData(nil) — e.g. CheckACL / CheckACLNoChannel or NewSessionAC receiving a nil envelope because a prior GetEnvelopeFromBlock / Unmarshal step failed or returned nil without propagating an error.","commonSituations":"ACL resource provider invoked with an envelope extracted from a malformed block; deliver sessions created with a nil envelope; tests exercising the nil case; transaction filters dropping payloads upstream leaving nil envelopes.","solutions":["Guard with a nil check on the envelope before calling EnvelopeAsSignedData and reject the request early.","Ensure GetEnvelopeFromBlock / proto unmarshaling errors are handled so nil envelopes never reach ACL checks.","When building envelopes programmatically, marshal a valid Payload into env.Payload before submission.","In tests, use a minimal valid envelope rather than nil to exercise the intended path."],"exampleFix":"// before\nsd, err := protoutil.EnvelopeAsSignedData(env)\n\n// after\nif env == nil {\n    return status.Error(codes.InvalidArgument, \"envelope is nil\")\n}\nsd, err := protoutil.EnvelopeAsSignedData(env)","handlingStrategy":"type-guard","validationCode":"if env == nil || len(env.Payload) == 0 {\n    return errors.New(\"envelope with payload required\")\n}","typeGuard":"func validEnvelope(env *common.Envelope) bool {\n    return env != nil && len(env.Payload) > 0\n}","tryCatchPattern":"sd, err := protoutil.EnvelopeAsSignedData(env)\nif err != nil {\n    return fmt.Errorf(\"cannot check ACL: %w\", err)\n}","preventionTips":["Ensure GetEnvelopeFromBlock errors are propagated, not swallowed into a nil envelope.","Nil-check envelopes before ACL checks (CheckACL / NewSessionAC).","Build envelopes with protoutil helpers so Payload is always marshaled.","In deliver/eval paths, reject envelopes with empty payload bytes early."],"tags":["fabric","envelope","signature","nil-envelope"],"backgroundTag":"nil-envelope-signature","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"}