{"record":{"id":"6029df2f3d9e8b3b","repo":"hyperledger/fabric","slug":"could-not-acquire-policy-manager-for-channel-s","errorCode":null,"errorMessage":"Could not acquire policy manager for channel %s","messagePattern":"Could not acquire policy manager for channel (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/peer/gossip/mcs.go","lineNumber":170,"sourceCode":"\n\tdataHash, err := protoutil.BlockDataHash(block.Data)\n\tif err != nil {\n\t\treturn err\n\t}\n\t// - Verify that Header.DataHash is equal to the hash of block.Data\n\t// This is to ensure that the header is consistent with the data carried by this block\n\tif !bytes.Equal(dataHash, block.Header.DataHash) {\n\t\treturn fmt.Errorf(\"Header.DataHash is different from Hash(block.Data) for block with id [%d] on channel [%s]\", block.Header.Number, chainID)\n\t}\n\n\treturn s.verifyHeaderAndMetadata(channelID, block)\n}\n\nfunc (s *MSPMessageCryptoService) verifyHeaderAndMetadata(channelID string, block *pcommon.Block) error {\n\t// Get the policy manager for channelID\n\tcpm := s.channelPolicyManagerGetter.Manager(channelID)\n\tif cpm == nil {\n\t\treturn fmt.Errorf(\"Could not acquire policy manager for channel %s\", channelID)\n\t}\n\tmcsLogger.Debugf(\"Got policy manager for channel [%s]\", channelID)\n\n\t// Get block validation policy\n\tpolicy, ok := cpm.GetPolicy(policies.BlockValidation)\n\t// ok is true if it was the policy requested, or false if it is the default policy\n\tmcsLogger.Debugf(\"Got block validation policy for channel [%s] with flag [%t]\", channelID, ok)\n\n\tchConfig := s.channelConfigGetter(channelID)\n\tbftEnabled := chConfig.ChannelConfig().Capabilities().ConsensusTypeBFT()\n\n\tvar consenters []*pcommon.Consenter\n\tif bftEnabled {\n\t\tcfg, ok := chConfig.OrdererConfig()\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"no orderer section in channel config for channel [%s].\", channelID)\n\t\t}\n\t\tconsenters = cfg.Consenters()","sourceCodeStart":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/internal/peer/gossip/mcs.go#L152-L188","documentation":"MSPMessageCryptoService.verifyHeaderAndMetadata could not retrieve a channel policy manager (PolicyManager) for the given channelID from the channelPolicyManagerGetter. This means the peer has no policy manager registered for that channel, so block-verification policy (policies.BlockValidation) cannot be resolved and the block cannot be verified. The service intentionally fails closed rather than skipping verification.","triggerScenarios":"VerifyBlock or VerifyBlockAttestation is invoked for a channel whose policy manager getter returns nil from Manager(channelID) — i.e., the channel is not initialized on this peer or the channel policy manager lookup happens before channel config/resources are loaded.","commonSituations":"Peer receiving gossip state/block messages for a channel it has not joined yet; channel ID mismatch (typo or wrong chainID passed); peer starting up and gossip messages arriving before channel resources (channelconfig) are committed; stale gossip membership after a channel was removed from the peer.","solutions":["Verify the peer has actually joined the channel (peer channel list); join it if not.","Ensure block/crypto material is only processed after the channel is initialized on the peer.","Check the channelID string passed to VerifyBlock/VerifyBlockAttestation matches the real channel name exactly.","Restart the peer so channel resources are rebuilt from the ledger/config.","Check for race/ordering issues: gossip delivery before channelconfig commit (peer logs around channel init)."],"exampleFix":"// before: verifying gossip blocks blindly\nif err := cryptoService.VerifyBlock(channelID, block); err != nil { ... }\n// after: ensure channel is known to the peer first\nif peerChannelPolicyManagerGetter.Manager(channelID) == nil {\n    return fmt.Errorf(\"channel %s not joined on this peer; skipping verification\", channelID)\n}\nif err := cryptoService.VerifyBlock(channelID, block); err != nil { ... }","handlingStrategy":"validation","validationCode":"if peerPolicyManagerGetter.Manager(channelID) == nil {\n    return fmt.Errorf(\"channel %s not initialized on peer; cannot verify block\", channelID)\n}","typeGuard":"func channelKnown(getter api.ChannelPolicyManagerGetter, channelID string) bool {\n    return getter.Manager(channelID) != nil\n}","tryCatchPattern":"if err := cryptoService.VerifyBlock(channelID, block); err != nil {\n    if strings.Contains(err.Error(), \"Could not acquire policy manager\") {\n        log.Warnf(\"channel %s not ready for verification; deferring block\", channelID)\n        return errDeferred\n    }\n    return err\n}","preventionTips":["Join the channel on the peer before processing its gossip blocks","Validate channel names against peer channel list before verification","Order startup so channel initialization completes before state sync consumption","Monitor peer logs for channelconfig commit failures"],"tags":["hyperledger-fabric","gossip","msp","policy-manager","channel"],"backgroundTag":"channel-policy-manager-not-found","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"}