hyperledger/fabric · error

data unmarshalling error: %s

Error message

data unmarshalling error: %s

What it means

ValidateConfig in orderer/consensus/smartbft/configverifier.go:86 returns "data unmarshalling error: %s" when, for an envelope typed HeaderType_CONFIG, proto.Unmarshal of payload.Data into common.ConfigEnvelope fails. The envelope claims to be a config transaction, but its Data section is not a valid protobuf ConfigEnvelope.

Source

Thrown at orderer/consensus/smartbft/configverifier.go:86

	if payload.Header == nil {
		return fmt.Errorf("no header was set")
	}

	if payload.Header.ChannelHeader == nil {
		return fmt.Errorf("no channel header was set")
	}

	chdr, err := protoutil.UnmarshalChannelHeader(payload.Header.ChannelHeader)
	if err != nil {
		return fmt.Errorf("channel header unmarshalling error: %s", err)
	}

	switch chdr.Type {
	case int32(common.HeaderType_CONFIG):
		configEnvelope := &common.ConfigEnvelope{}
		if err = proto.Unmarshal(payload.Data, configEnvelope); err != nil {
			return fmt.Errorf("data unmarshalling error: %s", err)
		}
		return cbv.verifyConfigUpdateMsg(envelope, configEnvelope, chdr)
	default:
		return errors.Errorf("unexpected envelope type %s", common.HeaderType_name[chdr.Type])
	}
}

func (cbv *ConfigBlockValidator) checkConsentersMatchPolicy(conf *common.Config) error {
	if conf == nil {
		return fmt.Errorf("empty Config")
	}

	if conf.ChannelGroup == nil {
		return fmt.Errorf("empty channel group")
	}

	if len(conf.ChannelGroup.Groups) == 0 {
		return fmt.Errorf("no groups in channel group")

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Ensure the CONFIG-typed envelope's Data is a marshaled common.ConfigEnvelope{Config: &common.Config{...}} (containing ChannelGroup/Config/LastUpdate), not a bare ConfigUpdate.
  2. Let the SDK/orderer construct the config envelope (submit a CONFIG_UPDATE envelope and let ProcessConfigUpdateMsg wrap it) rather than hand-building.
  3. Verify payload.Data was produced by proto.Marshal on a ConfigEnvelope, and re-marshal after any struct mutation.
  4. If the data came from a block, check block integrity and re-read from another orderer.

Example fix

// before: raw ConfigUpdate marshaled as CONFIG envelope data
payload.Data = protoutil.MarshalOrPanic(configUpdate)
// after
configEnvelope := &common.ConfigEnvelope{Config: &common.Config{LastUpdate: configUpdate}}
payload.Data = protoutil.MarshalOrPanic(configEnvelope)
Defensive patterns

Strategy: validation

Validate before calling

if chdr.Type == int32(common.HeaderType_CONFIG) {
    probe := &common.ConfigEnvelope{}
    if err := proto.Unmarshal(payload.Data, probe); err != nil {
        return fmt.Errorf("CONFIG payload data is not a ConfigEnvelope: %w", err)
    }
    if probe.Config == nil {
        return errors.New("ConfigEnvelope.Config is nil")
    }
}

Type guard

func isConfigEnvelope(data []byte) (*common.ConfigEnvelope, bool) {
    ce := &common.ConfigEnvelope{}
    if err := proto.Unmarshal(data, ce); err != nil || ce.Config == nil {
        return nil, false
    }
    return ce, true
}

Try / catch

if err := cbv.ValidateConfig(envelope); err != nil {
    if strings.Contains(err.Error(), "data unmarshalling error") {
        return fmt.Errorf("CONFIG envelope data invalid: wrap the ConfigUpdate in common.ConfigEnvelope{Config: ...}")
    }
    return err
}

Prevention

When it happens

Trigger: chdr.Type == HeaderType_CONFIG and proto.Unmarshal(payload.Data, configEnvelope) returns an error — payload.Data holds malformed bytes, a different message type (e.g. a Transaction or ConfigUpdate instead of ConfigEnvelope), or corrupted data.

Common situations: A client wrapping a raw ConfigUpdate in a CONFIG envelope instead of letting the orderer's ProcessConfigUpdateMsg build the ConfigEnvelope; hand-built config envelopes in tooling/tests; corrupted ledger blocks; cross-version serialization bugs in custom submission paths.

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/b98c25cd7189aca4. Report an issue: GitHub.