hyperledger/fabric · error

requested sequence is 0, but first definable sequence number

Error message

requested sequence is 0, but first definable sequence number is 1

What it means

The approved chaincode definition was submitted with Sequence 0 while the currently committed sequence for the namespace is also 0 (nothing committed yet). Lifecycle requires the first definable sequence to be 1, so a zero sequence is invalid in every case.

Source

Thrown at core/chaincode/lifecycle/lifecycle.go:431

	}

	return nil
}

// ApproveChaincodeDefinitionForOrg adds a chaincode definition entry into the passed in Org state.  The definition must be
// for either the currently defined sequence number or the next sequence number.  If the definition is
// for the current sequence number, then it must match exactly the current definition or it will be rejected.
func (ef *ExternalFunctions) ApproveChaincodeDefinitionForOrg(chname, ccname string, cd *ChaincodeDefinition, packageID string, publicState ReadableState, orgState ReadWritableState) error {
	// Get the current sequence from the public state
	currentSequence, err := ef.Resources.Serializer.DeserializeFieldAsInt64(NamespacesName, ccname, "Sequence", publicState)
	if err != nil {
		return errors.WithMessage(err, "could not get current sequence")
	}

	requestedSequence := cd.Sequence

	if currentSequence == requestedSequence && requestedSequence == 0 {
		return errors.Errorf("requested sequence is 0, but first definable sequence number is 1")
	}

	if requestedSequence < currentSequence {
		return errors.Errorf("currently defined sequence %d is larger than requested sequence %d", currentSequence, requestedSequence)
	}

	if requestedSequence > currentSequence+1 {
		return errors.Errorf("requested sequence %d is larger than the next available sequence number %d", requestedSequence, currentSequence+1)
	}

	if err := ef.SetChaincodeDefinitionDefaults(chname, cd); err != nil {
		return errors.WithMessagef(err, "could not set defaults for chaincode definition in channel %s", chname)
	}

	privateName := fmt.Sprintf("%s#%d", ccname, requestedSequence)

	if requestedSequence == currentSequence {
		metadata, ok, err := ef.Resources.Serializer.DeserializeMetadata(NamespacesName, ccname, publicState)

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Resubmit the approval with --sequence 1 for the first definition
  2. Compute the next sequence as (last committed sequence + 1) via querycommitted
  3. Fix deployment scripts to default the sequence to 1 when no prior definition exists

Example fix

// before
peer lifecycle chaincode approveformyorg -C mychannel --sequence 0
// after
peer lifecycle chaincode approveformyorg -C mychannel --sequence 1
Defensive patterns

Strategy: validation

Validate before calling

// Ensure sequence >= 1 before approving
if def.Sequence < 1 {
    return fmt.Errorf("sequence must be >= 1 for first definition; got %d", def.Sequence)
}
// then approve

Type guard

func validFirstSequence(seq int64) bool { return seq >= 1 }

Try / catch

err := ef.ApproveChaincodeDefinitionForOrg(...)
if err != nil && strings.Contains(err.Error(), "first definable sequence number is 1") {
    def.Sequence = 1
    err = ef.ApproveChaincodeDefinitionForOrg(...)
}

Prevention

When it happens

Trigger: Calling ApproveChaincodeDefinitionForOrg (or 'peer lifecycle chaincode approveformyorg') with --sequence 0 for a chaincode that has never been defined on the channel.

Common situations: Copy-paste of approve commands with an unset/placeholder sequence value; scripts computing sequence numbers incorrectly; first-time deployment where operators forget the sequence starts at 1.

Related errors


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