hyperledger/fabric · error

failed to extract payload from config envelope

Error message

failed to extract payload from config envelope

What it means

After the config envelope is obtained, ConsensusMetadataFromConfigBlock unmarshals its payload with protoutil.UnmarshalPayload. This error means the envelope's Payload bytes are empty or not valid protobuf — the config envelope itself is malformed even though it was extracted successfully.

Source

Thrown at orderer/consensus/etcdraft/util.go:193

// ConsensusMetadataFromConfigBlock reads consensus metadata updates from the configuration block
func ConsensusMetadataFromConfigBlock(block *common.Block) (*etcdraft.ConfigMetadata, *orderer.ConsensusType, error) {
	if block == nil {
		return nil, nil, errors.New("nil block")
	}

	if !protoutil.IsConfigBlock(block) {
		return nil, nil, errors.New("not a config block")
	}

	configEnvelope, err := ConfigEnvelopeFromBlock(block)
	if err != nil {
		return nil, nil, errors.Wrap(err, "cannot read config update")
	}

	payload, err := protoutil.UnmarshalPayload(configEnvelope.GetPayload())
	if err != nil {
		return nil, nil, errors.Wrap(err, "failed to extract payload from config envelope")
	}
	// get config update
	configUpdate, err := configtx.UnmarshalConfigUpdateFromPayload(payload)
	if err != nil {
		return nil, nil, errors.Wrap(err, "could not read config update")
	}

	return MetadataFromConfigUpdate(configUpdate)
}

// VerifyConfigMetadata validates Raft config metadata.
// Note: ignores certificates expiration.
func VerifyConfigMetadata(metadata *etcdraft.ConfigMetadata, verifyOpts x509.VerifyOptions) error {
	if metadata == nil {
		// defensive check. this should not happen as CheckConfigMetadata
		// should always be called with non-nil config metadata
		return errors.Errorf("nil Raft config metadata")
	}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Re-fetch the config block from another ordering node or an on-demand backup to replace the corrupted data.
  2. Verify the envelope was constructed with marshaled Payload bytes (protoutil.MarshalOrPanic on a common.Payload) before insertion in tests.
  3. Check ledger storage integrity (filelocks, filesystem errors) and consider rebuilding the node from a snapshot if corruption recurs.

Example fix

// before
env := &common.Envelope{Signature: sig} // Payload left nil

// after
payload := protoutil.MarshalOrPanic(&common.Payload{Header: hdr, Data: configData})
env := &common.Envelope{Payload: payload, Signature: sig}
Defensive patterns

Strategy: validation

Validate before calling

if len(configEnvelope.GetPayload()) == 0 {
    return errors.New("config envelope has empty payload")
}

Type guard

func hasPayload(envelope *common.Envelope) bool {
    return envelope != nil && len(envelope.GetPayload()) > 0
}

Try / catch

meta, _, err := ConsensusMetadataFromConfigBlock(block)
if err != nil {
    if strings.Contains(err.Error(), "failed to extract payload from config envelope") {
        return errors.Wrap(err, "corrupt config envelope payload; restore block from backup")
    }
    return err
}

Prevention

When it happens

Trigger: Envelope at block index 0 has a nil/empty or corrupted Payload field while still being extractable as an Envelope; bit-rot or truncation in stored block data.

Common situations: Disk corruption on the ordering node's ledger; blocks copied between nodes/filesystems incorrectly; synthetic test envelopes with unset Payload.

Related errors


AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04). Data as JSON: /api/errors/a41f7afaabffdd6d. Report an issue: GitHub.