hyperledger/fabric · error

requested sequence is %d, but new definition must be sequenc

Error message

requested sequence is %d, but new definition must be sequence %d

What it means

Thrown by CheckCommitReadiness when the sequence number in the proposed ChaincodeDefinition does not equal the currently committed sequence plus one. Lifecycle requires definitions to be committed strictly sequentially; gaps or repeats are rejected.

Source

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

	BuildRegistry             *container.BuildRegistry
	mutex                     sync.Mutex
	BuildLocks                map[string]*sync.Mutex
	concurrentInstalls        uint32
}

// CheckCommitReadiness takes a chaincode definition, checks that
// its sequence number is the next allowable sequence number and checks which
// organizations have approved the definition.
func (ef *ExternalFunctions) CheckCommitReadiness(chname, ccname string, cd *ChaincodeDefinition, publicState ReadWritableState, orgStates []OpaqueState) (approvals map[string]bool, mismatches map[string][]string, err error) {
	var currentSequence int64
	currentSequence, err = ef.Resources.Serializer.DeserializeFieldAsInt64(NamespacesName, ccname, "Sequence", publicState)
	if err != nil {
		err = errors.WithMessage(err, "could not get current sequence")
		return
	}

	if cd.Sequence != currentSequence+1 {
		err = errors.Errorf("requested sequence is %d, but new definition must be sequence %d", cd.Sequence, currentSequence+1)
		return
	}

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

	if approvals, mismatches, err = ef.QueryOrgApprovals(ccname, cd, orgStates); err != nil {
		return
	}

	logger.Infof("Successfully checked commit readiness of chaincode name '%s' on channel '%s' with definition {%s}", ccname, chname, cd)

	return
}

// CommitChaincodeDefinition takes a chaincode definition, checks that its

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Query the current committed sequence ('peer lifecycle chaincode querycommitted') and set sequence to current+1
  2. If the definition is unchanged and already committed, no action is needed — the commit is redundant
  3. Increment the sequence exactly once for each new definition change and re-approve on all orgs

Example fix

// before
approveformyorg --sequence 1 // committed sequence is already 1
// after
approveformyorg --sequence 2 // current sequence 1 + 1
Defensive patterns

Strategy: validation

Validate before calling

committed, err := lifecycleQueryCommitted(chname, ccname, publicState)
if err != nil { committedSeq = 0 } else { committedSeq = committed.Sequence }
if cd.Sequence != committedSeq+1 {
    return fmt.Errorf("set --sequence to %d (current committed sequence is %d)", committedSeq+1, committedSeq)
}

Type guard

func nextSequence(committedSeq uint64) uint64 { return committedSeq + 1 }

Try / catch

if err := lifecycle.CheckCommitReadiness(chname, cd, ...); err != nil {
    if strings.Contains(err.Error(), "requested sequence is") {
        // re-query committed sequence and resubmit with current+1
    }
    return err
}

Prevention

When it happens

Trigger: Committing/approving a definition with cd.Sequence lower or higher than currentSequence+1 — e.g. re-committing the same sequence after it is already committed, or skipping a sequence number.

Common situations: Re-running the same approve/commit command twice; multiple operators incrementing sequences independently causing a gap; stale knowledge of the current committed sequence after other orgs committed an update.

Related errors


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