{"record":{"id":"d7083edbb39d7fa6","repo":"hyperledger/fabric","slug":"not-a-config-block-d7083e","errorCode":null,"errorMessage":"not a config block","messagePattern":"not a config block","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"orderer/consensus/etcdraft/util.go","lineNumber":183,"sourceCode":"\n\tswitch channelHeader.GetType() {\n\tcase int32(common.HeaderType_ORDERER_TRANSACTION):\n\t\treturn nil, errors.Errorf(\"unsupported legacy system channel header type: %v\", channelHeader.GetType())\n\tcase int32(common.HeaderType_CONFIG):\n\t\treturn envelope, nil\n\tdefault:\n\t\treturn nil, errors.Errorf(\"unexpected header type: %v\", channelHeader.GetType())\n\t}\n}\n\n// ConsensusMetadataFromConfigBlock reads consensus metadata updates from the configuration block\nfunc ConsensusMetadataFromConfigBlock(block *common.Block) (*etcdraft.ConfigMetadata, *orderer.ConsensusType, error) {\n\tif block == nil {\n\t\treturn nil, nil, errors.New(\"nil block\")\n\t}\n\n\tif !protoutil.IsConfigBlock(block) {\n\t\treturn nil, nil, errors.New(\"not a config block\")\n\t}\n\n\tconfigEnvelope, err := ConfigEnvelopeFromBlock(block)\n\tif err != nil {\n\t\treturn nil, nil, errors.Wrap(err, \"cannot read config update\")\n\t}\n\n\tpayload, err := protoutil.UnmarshalPayload(configEnvelope.GetPayload())\n\tif err != nil {\n\t\treturn nil, nil, errors.Wrap(err, \"failed to extract payload from config envelope\")\n\t}\n\t// get config update\n\tconfigUpdate, err := configtx.UnmarshalConfigUpdateFromPayload(payload)\n\tif err != nil {\n\t\treturn nil, nil, errors.Wrap(err, \"could not read config update\")\n\t}\n\n\treturn MetadataFromConfigUpdate(configUpdate)","sourceCodeStart":165,"sourceCodeEnd":201,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/consensus/etcdraft/util.go#L165-L201","documentation":"ConsensusMetadataFromConfigBlock validates its input with protoutil.IsConfigBlock and returns this error if the block's last envelope is not of config type. The function only reads Raft consensus metadata from configuration blocks, so any ordinary transaction block is rejected.","triggerScenarios":"Passing a regular (transaction) block — not HeaderType_CONFIG — into ConsensusMetadataFromConfigBlock, e.g. forwarding every delivered block instead of only config blocks.","commonSituations":"Block-deliver handlers that fail to filter on header type; using the wrong block number when inspecting raft config changes; replaying a channel from a snapshot and handing the first non-config block to the parser.","solutions":["Check protoutil.IsConfigBlock(block) at the call site and skip non-config blocks.","Subscribe to config-update events or filter delivered blocks on HeaderType_CONFIG before parsing.","Ensure the block passed is the actual latest config block from the channel's config history."],"exampleFix":"// before\nfor block := range blocks {\n    meta, _, err := ConsensusMetadataFromConfigBlock(block)\n    ...\n}\n\n// after\nfor block := range blocks {\n    if !protoutil.IsConfigBlock(block) {\n        continue // ordinary tx block, not a config update\n    }\n    meta, _, err := ConsensusMetadataFromConfigBlock(block)\n    ...\n}","handlingStrategy":"validation","validationCode":"if !protoutil.IsConfigBlock(block) {\n    return errors.New(\"input is not a config block\")\n}","typeGuard":"func isUsableConfigBlock(block *common.Block) bool {\n    return block != nil && protoutil.IsConfigBlock(block)\n}","tryCatchPattern":"meta, _, err := ConsensusMetadataFromConfigBlock(block)\nif err != nil {\n    if err.Error() == \"not a config block\" {\n        return nil // non-config block: safe to ignore\n    }\n    return err\n}","preventionTips":["Always gate this call with protoutil.IsConfigBlock.","Filter delivered blocks on HeaderType_CONFIG in event handlers.","Fetch config blocks via the ledger's config history, not arbitrary block numbers."],"tags":["hyperledger-fabric","etcdraft","config-block","validation"],"backgroundTag":"wrong-block-type","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}