hyperledger/fabric · error

invalid header type %s

Error message

invalid header type %s

What it means

validateChannelHeader only accepts ChannelHeader types ENDORSER_TRANSACTION, CONFIG_UPDATE, and CONFIG. Any other HeaderType (e.g. MESSAGE, DELIVER_SEEK_INFO, PEER_RESOURCE_UPDATE) reaches the default case and is rejected with this formatted error including the type's string name.

Source

Thrown at core/common/validation/msgvalidation.go:99

	}

	return nil
}

// checks for a valid ChannelHeader
func validateChannelHeader(cHdr *common.ChannelHeader) error {
	// check for nil argument
	if cHdr == nil {
		return errors.New("nil ChannelHeader provided")
	}

	// validate the header type
	switch common.HeaderType(cHdr.Type) {
	case common.HeaderType_ENDORSER_TRANSACTION:
	case common.HeaderType_CONFIG_UPDATE:
	case common.HeaderType_CONFIG:
	default:
		return errors.Errorf("invalid header type %s", common.HeaderType(cHdr.Type))
	}

	putilsLogger.Debugf("validateChannelHeader info: header type %d", common.HeaderType(cHdr.Type))

	// TODO: validate channelID in cHdr.ChannelID

	// Validate epoch in cHdr.Epoch
	// Currently we enforce that Epoch is 0.
	// TODO: This check will be modified once the Epoch management
	// will be in place.
	if cHdr.Epoch != 0 {
		return errors.Errorf("invalid Epoch in ChannelHeader. Expected 0, got [%d]", cHdr.Epoch)
	}

	// TODO: Validate version in cHdr.Version

	return nil
}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Set ChannelHeader.Type to common.HeaderType_ENDORSER_TRANSACTION for regular transaction submissions
  2. Use CONFIG or CONFIG_UPDATE only through the config-update path (configtxgen / channel update flow)
  3. Check the numeric/enum value in the client SDK maps to a valid Fabric HeaderType
  4. Verify you are routing deliver/seek or other internal messages through the correct service, not transaction validation

Example fix

// before
chdr := protoutil.MakeChannelHeader(common.HeaderType_MESSAGE, 0, channelID, txid)
// after
chdr := protoutil.MakeChannelHeader(common.HeaderType_ENDORSER_TRANSACTION, 0, channelID, txid)
Defensive patterns

Strategy: validation

Validate before calling

func headerTypeAllowed(t common.HeaderType) bool {
    switch t {
    case common.HeaderType_ENDORSER_TRANSACTION, common.HeaderType_CONFIG, common.HeaderType_CONFIG_UPDATE:
        return true
    }
    return false
}

Try / catch

if err != nil && strings.HasPrefix(err.Error(), "invalid header type") {
    // set the correct HeaderType constant and rebuild the envelope
}

Prevention

When it happens

Trigger: Submitting or validating a payload whose ChannelHeader.Type is not one of the three accepted values — e.g. a client sending a HeaderType_MESSAGE envelope through ValidateTransaction, or a mislabeled header type constant.

Common situations: Clients reusing envelope-construction code with the wrong header type constant; internal messages (like deliver/seek requests) mistakenly routed through transaction validation; numeric type fields set by hand with wrong enum values; Fabric version changes adding new header types not accepted here.

Related errors


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