hyperledger/fabric · error

empty Config

Error message

empty Config

What it means

checkConsentersMatchPolicy requires a non-nil *common.Config to inspect the channel's consenter set and BlockValidation policy. A nil Config means the config envelope carried no Config at all, so there is nothing to validate, and the verifier fails fast with 'empty Config'.

Source

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

	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")
	}

	if conf.ChannelGroup.Groups["Orderer"] == nil {
		return fmt.Errorf("no 'Orderer' group in channel groups")
	}

	if len(conf.ChannelGroup.Groups["Orderer"].Values) == 0 {
		return fmt.Errorf("no values in 'Orderer' group")
	}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Ensure the ConfigEnvelope.Config field is populated with the full channel *common.Config before the block is committed/validated
  2. Re-fetch the config block from the ordering service in case the envelope was truncated or corrupted
  3. If constructing the envelope in tests, set LastUpdate and Config explicitly (e.g. via configtx tooling output)

Example fix

// before
confEnv := &common.ConfigEnvelope{LastUpdate: update} // Config is nil
// after
confEnv := &common.ConfigEnvelope{LastUpdate: update, Config: config}
Defensive patterns

Strategy: validation

Validate before calling

func hasConfig(confEnv *common.ConfigEnvelope) bool {
  return confEnv != nil && confEnv.Config != nil
}

Type guard

func isPopulatedConfig(c *common.Config) bool { return c != nil }

Try / catch

if err := cbv.ValidateConfig(envelope); err != nil {
  if strings.Contains(err.Error(), "empty Config") {
    return fmt.Errorf("config block is malformed: %w", err)
  }
  return err
}

Prevention

When it happens

Trigger: Calling ValidateConfig on a CONFIG envelope whose ConfigEnvelope.Config is nil (verifyConfigUpdateMsg passes confEnv.Config straight into checkConsentersMatchPolicy). Note verifyConfigUpdateMsg already rejects confEnv==nil, so this fires when the Config field itself is nil.

Common situations: Hand-crafted or corrupted config blocks missing the Config field; deserialization producing an empty ConfigEnvelope; tooling that builds config envelopes programmatically and forgets to populate Config.

Related errors


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