hyperledger/fabric · error
config block channel ID [%s] does not match expected: [%s]
Error message
config block channel ID [%s] does not match expected: [%s]
What it means
UpdateConfig validates that the config block belongs to the channel the verification assistant was constructed for. If the ChannelHeader's channel ID differs from a.channelID, the config block cannot be applied to this channel's verifier and the mismatch is reported with both values.
Source
Thrown at common/deliverclient/block_verification.go:221
return errors.WithMessage(err, "error extracting envelope")
}
payload, err := protoutil.UnmarshalPayload(configTx.Payload)
if err != nil {
return errors.WithMessage(err, "error unmarshalling envelope to payload")
}
if payload.Header == nil {
return errors.New("missing channel header")
}
chdr, err := protoutil.UnmarshalChannelHeader(payload.Header.ChannelHeader)
if err != nil {
return errors.WithMessage(err, "error unmarshalling channel header")
}
if chdr.GetChannelId() != a.channelID {
return errors.Errorf("config block channel ID [%s] does not match expected: [%s]", chdr.GetChannelId(), a.channelID)
}
configEnvelope, err := configtx.UnmarshalConfigEnvelope(payload.Data)
if err != nil {
return errors.WithMessage(err, "error unmarshalling config envelope from payload data")
}
verifierFunc, err := a.verifierAssembler.VerifierFromConfig(configEnvelope, chdr.GetChannelId())
if err != nil {
return errors.WithMessage(err, "error creating verifier function")
}
a.configBlockHeader = configBlock.Header
a.lastBlockHeader = configBlock.Header
a.lastBlockHeaderHash = protoutil.BlockHeaderHash(configBlock.Header)
a.sigVerifierFunc = verifierFunc
return nilView on GitHub (pinned to 2736b63f8f)
Solutions
- Construct the deliver client / verification assistant with the correct channel ID matching the ledger being delivered.
- Check the delivered block's chdr.ChannelId (e.g. protoutil.GetChannelIDFromBlock) and route it to a matching assistant.
- Fix typos/case mismatches in channel configuration.
Example fix
// before
client, _ := NewDeliverClient("orderer:7050", "mychannel", ...) // typo'd id
// after
blockChannel := protoutil.GetChannelIDFromBlock(configBlock)
client, _ := NewDeliverClient("orderer:7050", blockChannel, ...) Defensive patterns
Strategy: validation
Validate before calling
blockChannelID, err := protoutil.GetChannelIDFromBlock(configBlock)
if err != nil { return err }
if blockChannelID != expectedChannelID {
return fmt.Errorf("block is for channel %s, not %s", blockChannelID, expectedChannelID)
} Type guard
func matchesChannel(block *common.Block, want string) bool {
got, err := protoutil.GetChannelIDFromBlock(block)
return err == nil && got == want
} Try / catch
if err := bva.UpdateConfig(env); err != nil {
if strings.Contains(err.Error(), "does not match expected") {
// recreate assistant with the block's actual channel ID
}
return err
} Prevention
- Copy channel IDs from configuration, not by hand-editing literals
- Route blocks to verification assistants keyed by chdr.ChannelId
- Remember channel IDs are case-sensitive; validate against the network config
When it happens
Trigger: Delivering/subscribing blocks for a different channel than the one the assistant was created with; the deliver client was constructed with the wrong channelID; a seek on the wrong channel config stream; tests reusing a client across channels.
Common situations: Multi-channel deployments where channel IDs are mixed up (case-sensitive, typo, ordering-system vs application channel name); copying client setup code for another channel without updating the ID.
Related errors
- last block header hash is missing
- missing channel header
- block must be different from nil, channel=%s
- transaction is aimed at channel %s but our channel is %s
- malformed org definition for org: %s
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/b59150d69bed6126.
Report an issue: GitHub.