{"record":{"id":"dddf55b68651dfd3","repo":"hyperledger/fabric","slug":"invalid-channel-id-name-during-check-policy-on-sig","errorCode":null,"errorMessage":"Invalid channel ID name during check policy on signed data. Name must be different from nil.","messagePattern":"Invalid channel ID name during check policy on signed data\\. Name must be different from nil\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/policy/policy.go","lineNumber":159,"sourceCode":"\t\treturn fmt.Errorf(\"Failed getting local MSP principal during channelless check policy with policy [%s]: [%s]\", policyName, err)\n\t}\n\n\t// Verify that proposal's creator satisfies the principal\n\terr = id.SatisfiesPrincipal(principal)\n\tif err != nil {\n\t\tlogger.Warnw(\"Failed verifying that proposal's creator satisfies local MSP principal during channelless check policy\", \"error\", err, \"policyName\", policyName, \"requiredPrincipal\", principal, \"signingIdentity\", protoutil.LogMessageForSerializedIdentity(shdr.Creator))\n\t\treturn fmt.Errorf(\"Failed verifying that proposal's creator satisfies local MSP principal during channelless check policy with policy [%s]: [%s]\", policyName, err)\n\t}\n\n\t// Verify the signature\n\treturn id.Verify(signedProp.ProposalBytes, signedProp.Signature)\n}\n\n// CheckPolicyBySignedData checks that the passed signed data is valid with the respect to\n// passed policy on the passed channel.\nfunc (p *policyChecker) CheckPolicyBySignedData(channelID, policyName string, sd []*protoutil.SignedData) error {\n\tif channelID == \"\" {\n\t\treturn errors.New(\"Invalid channel ID name during check policy on signed data. Name must be different from nil.\")\n\t}\n\n\tif policyName == \"\" {\n\t\treturn fmt.Errorf(\"Invalid policy name during check policy on signed data on channel [%s]. Name must be different from nil.\", channelID)\n\t}\n\n\tif sd == nil {\n\t\treturn fmt.Errorf(\"Invalid signed data during check policy on channel [%s] with policy [%s]\", channelID, policyName)\n\t}\n\n\t// Get Policy\n\tpolicyManager := p.channelPolicyManagerGetter.Manager(channelID)\n\tif policyManager == nil {\n\t\treturn fmt.Errorf(\"Failed to get policy manager for channel [%s]\", channelID)\n\t}\n\n\t// Recall that get policy always returns a policy object\n\tpolicy, _ := policyManager.GetPolicy(policyName)","sourceCodeStart":141,"sourceCodeEnd":177,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/policy/policy.go#L141-L177","documentation":"Returned by CheckPolicyBySignedData as an argument validation guard when the channelID parameter is an empty string. The library cannot look up a channel policy manager without a channel name, so it rejects the call up front. Despite the wording 'different from nil', the actual check is for an empty string in Go.","triggerScenarios":"Calling CheckPolicyBySignedData(\"\", policyName, sd), or calling it indirectly through CheckPolicy with a proposal whose channel header ChannelId is empty/unset (e.g. a malformed or channelless proposal passed to the channel path).","commonSituations":"Client SDK builds a proposal without setting the channel ID header field; a caller passes an empty config value for channel name (unset env var or empty YAML field); tests exercising invalid-argument paths.","solutions":["Set the channel ID in the proposal/channel header before invoking the policy check.","Fix the caller's configuration so the channel name is non-empty (check env vars/config files).","For genuinely channelless operations, use CheckPolicyNoChannel instead of CheckPolicyBySignedData."],"exampleFix":"// before\nerr := checker.CheckPolicyBySignedData(\"\", \"CHANNEL_READERS\", sd)\n// after\nif channelID == \"\" { return errors.New(\"channelID is required\") }\nerr := checker.CheckPolicyBySignedData(channelID, \"CHANNEL_READERS\", sd)","handlingStrategy":"validation","validationCode":"if channelID == \"\" {\n    return errors.New(\"channel ID must be a non-empty string before calling CheckPolicyBySignedData\")\n}","typeGuard":"func validChannelID(id string) bool {\n    if id == \"\" { return false }\n    // fabric channel name rules\n    re := regexp.MustCompile(`^[a-zA-Z0-9._-]+$`)\n    return re.MatchString(id)\n}","tryCatchPattern":null,"preventionTips":["Read channel ID from configuration with explicit non-empty checks at startup.","Set ChannelId in the channel header when constructing proposals; unit-test proposal builders.","Use constants/env validation for channel names instead of ad hoc strings."],"tags":["fabric","validation","channel","argument-error"],"backgroundTag":"empty-required-argument","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"}