hyperledger/fabric · error
nil block or nil header
Error message
nil block or nil header
What it means
ConsenterCertificate.IsConsenterOfChannel checks whether this consenter's certificate appears in a channel's orderer config by inspecting a config block. It throws errors.New("nil block or nil header") when the caller passes a configBlock that is nil or whose block header is nil, i.e. there is no usable block to inspect. It is a defensive precondition check before ExtractEnvelope.
Source
Thrown at orderer/consensus/etcdraft/util.go:363
return err
}
return nil
}
// ConsenterCertificate denotes a TLS certificate of a consenter
type ConsenterCertificate struct {
ConsenterCertificate []byte
CryptoProvider bccsp.BCCSP
Logger *flogging.FabricLogger
}
// IsConsenterOfChannel returns whether the caller is a consenter of a channel
// by inspecting the given configuration block.
// It returns nil if true, else returns an error.
func (conCert ConsenterCertificate) IsConsenterOfChannel(configBlock *common.Block) error {
if configBlock == nil || configBlock.GetHeader() == nil {
return errors.New("nil block or nil header")
}
envelopeConfig, err := protoutil.ExtractEnvelope(configBlock, 0)
if err != nil {
return err
}
bundle, err := channelconfig.NewBundleFromEnvelope(envelopeConfig, conCert.CryptoProvider)
if err != nil {
return err
}
oc, exists := bundle.OrdererConfig()
if !exists {
return errors.New("no orderer config in bundle")
}
m := &etcdraft.ConfigMetadata{}
if err := proto.Unmarshal(oc.ConsensusMetadata(), m); err != nil {
return err
}
View on GitHub (pinned to 2736b63f8f)
Solutions
- Ensure a valid config block is loaded (from genesis file or ledger) before calling IsConsenterOfChannel
- Check configBlock != nil && configBlock.GetHeader() != nil at the call site before invoking
- Fix the bootstrap path so the genesis block is correctly read/decoded (correct file path, ORDERER_GENERAL_GENESISMETHOD etc.)
Example fix
// before
err := conCert.IsConsenterOfChannel(nil)
// after
configBlock := retrieveConfigBlock(ledger)
if configBlock == nil || configBlock.GetHeader() == nil {
return errors.New("config block not available")
}
err := conCert.IsConsenterOfChannel(configBlock) Defensive patterns
Strategy: type-guard
Validate before calling
if configBlock == nil || configBlock.GetHeader() == nil {
return errors.New("valid config block required")
} Type guard
func isValidBlock(b *common.Block) bool {
return b != nil && b.GetHeader() != nil
} Prevention
- Always load the genesis/config block before membership checks
- Check errors from block-retrieval functions instead of using possibly-nil results
- Add nil-header assertions in tests for block-producing code
When it happens
Trigger: Calling IsConsenterOfChannel (e.g. during etcdraft chain start / cluster membership check) with a configBlock variable that was never populated or a zero-value common.Block whose Header was never set.
Common situations: Orderer startup before the genesis/config block was retrieved from the ledger or file; passing the result of a failed config-block lookup without checking for nil; unit tests constructing an empty &common.Block{}.
Related errors
- nil block
- nil block
- not a config block
- cannot read config update
- no channel configuration found in the config block
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/153bf67de13d39d6.
Report an issue: GitHub.