hyperledger/fabric · error

unmarshalling block: %s

Error message

unmarshalling block: %s

What it means

validateBlockChannelID unmarshals the --configBlock bytes into common.Block with proto.Unmarshal; any parse failure is wrapped as this error. It means the file is not a valid protobuf-encoded fabric block.

Source

Thrown at cmd/osnadmin/main.go:214

func readBodyBytes(body io.ReadCloser) ([]byte, error) {
	bodyBytes, err := io.ReadAll(body)
	if err != nil {
		return nil, fmt.Errorf("reading http response body: %s", err)
	}
	body.Close()

	return bodyBytes, nil
}

func errorOutput(err error) string {
	return fmt.Sprintf("Error: %s\n", err)
}

func validateBlockChannelID(blockBytes []byte, channelID string) error {
	block := &common.Block{}
	err := proto.Unmarshal(blockBytes, block)
	if err != nil {
		return fmt.Errorf("unmarshalling block: %s", err)
	}

	blockChannelID, err := protoutil.GetChannelIDFromBlock(block)
	if err != nil {
		return err
	}

	// quick sanity check that the orderer admin is joining
	// the channel they think they're joining.
	if channelID != blockChannelID {
		return fmt.Errorf("specified --channelID %s does not match channel ID %s in config block", channelID, blockChannelID)
	}

	return nil
}

func validateEnvelopeChannelID(envelopeBytes []byte, channelID string) error {
	envelope := &common.Envelope{}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Verify the file is a binary protobuf block (e.g. produced by `peer channel fetch config` or `configtxgen -outputBlock`).
  2. Re-fetch or regenerate the config block.
  3. Ensure the file was not corrupted or truncated in transfer.
  4. Confirm you passed the block to --configBlock, not the envelope.

Example fix

// before
osnadmin channel join --channelID mychannel --configBlock config_update_envelope.pb
// after
osnadmin channel join --channelID mychannel --configBlock mychannel.block
Defensive patterns

Strategy: validation

Validate before calling

func looksLikeBlock(b []byte) bool {
    block := &common.Block{}
    return proto.Unmarshal(b, block) == nil
}
// run before invoking osnadmin join

Type guard

func isProtoBlock(b []byte) bool {
    blk := &common.Block{}
    if proto.Unmarshal(b, blk) != nil { return false }
    return blk.Header != nil && blk.Data != nil
}

Try / catch

if err := runOsnadmin(); err != nil {
    if strings.Contains(err.Error(), "unmarshalling block:") {
        log.Fatalf("--configBlock is not a valid protobuf block: %v", err)
    }
}

Prevention

When it happens

Trigger: Passing a text/gzip file, an envelope instead of a block, a truncated or corrupted block, or an empty file as --configBlock.

Common situations: Using an old serialized block from an incompatible fabric version, transferring the file with corruption (e.g. wrong binary mode), or mixing up the config update envelope with the config block.

Understand the failure class

Background: "cannot parse invalid wire-format data", "cannot unmarshal", "failed unmarshalling": protobuf unmarshal errors explained — this error's family across 10 libraries.

Related errors


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