hyperledger/fabric · error
cannot override peer type policy for channeless ACL check
Error message
cannot override peer type policy for channeless ACL check
What it means
CheckACLNoChannel is the channel-less ACL check; it delegates to the default (peer-type based) provider only when the resource uses default behavior. If the caller attempts to override the peer type policy for a resource that has a channel-less ACL check configured, the provider refuses with this error, since channel-less checks must always enforce the built-in peer type policy.
Source
Thrown at core/aclmgmt/resourceprovider.go:195
if resCfg != nil {
pp := &aclmgmtPolicyProviderImpl{&policyEvaluatorImpl{resCfg}}
policyName := pp.GetPolicyName(resName)
if policyName != "" {
aclLogger.Debugf("acl policy %s found in config for resource %s", policyName, resName)
return pp.CheckACL(policyName, idinfo)
}
aclLogger.Debugf("acl policy not found in config for resource %s", resName)
}
}
return rp.defaultProvider.CheckACL(resName, channelID, idinfo)
}
// CheckACLNoChannel implements the ACLProvider interface function
func (rp *resourceProvider) CheckACLNoChannel(resName string, idinfo any) error {
if !rp.enforceDefaultBehavior(resName, "", idinfo) {
return fmt.Errorf("cannot override peer type policy for channeless ACL check")
}
return rp.defaultProvider.CheckACLNoChannel(resName, idinfo)
}
View on GitHub (pinned to 2736b63f8f)
Solutions
- Use only the supported channel-less resource names (e.g. resources in the builtin peer-type policy list such as _lifecycle checks).
- If the resource is channel-scoped, call CheckACL with the channel ID instead of CheckACLNoChannel.
- Review custom resource/ACL registrations (resourceprovider config) and remove overrides for channel-less resources.
- Check enforceDefaultBehavior's accepted resource list to confirm the resource qualifies.
Example fix
// before
err := aclProvider.CheckACLNoChannel("my/custom/resource", id)
// after: use channel-scoped check for non-default resources
err := aclProvider.CheckACL("my/custom/resource", channelID, id) Defensive patterns
Strategy: validation
Validate before calling
var channellessResources = map[string]bool{
resources.LsccInstallsyscc: true,
// ... only resources valid for CheckACLNoChannel
}
if !channellessResources[resName] {
// use CheckACL with channelID instead
} Type guard
func isChannellessResource(resName string) bool {
return strings.HasPrefix(resName, "lscc/") // plus any known channel-less resource prefixes
} Try / catch
err := aclProvider.CheckACLNoChannel(resName, idInfo)
if err != nil && strings.Contains(err.Error(), "cannot override peer type policy") {
// fall back to channel-scoped CheckACL(resName, channelID, idInfo)
} Prevention
- Call CheckACLNoChannel only with built-in channel-less resources
- Use CheckACL with a channel ID for any custom or channel-scoped resource
- Do not register channel-scoped overrides for resources meant to be checked channel-lessly
When it happens
Trigger: Calling CheckACLNoChannel(resName, idinfo) for a resource name whose default behavior is not enforceable (rp.enforceDefaultBehavior returns false) — i.e., an ACL resource not among the supported channel-less resources, or a custom resource registration attempting to override it.
Common situations: Chaincode or system component passing an arbitrary/non-standard resource name to the channel-less check; lifecycle code (e.g. _lifecycle checks like IsLosCheckCommitReadinessEnabled) invoked against a resource registered with a channel-scoped override; misconfiguration of the resource-based ACL mapping.
Related errors
- Empty policy element
- failed to initialize block verifier function
- block numbers not maintained in index
- transaction IDs not maintained in index
- Invalid Proposal's SignatureHeader during check policy [%s]:
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/a217a9e2cc62a828.
Report an issue: GitHub.