hyperledger/fabric · error
empty nonce
Error message
empty nonce
What it means
The SignatureHeader's Nonce is empty. Fabric requires every endorser transaction to carry a fresh random nonce that, together with the creator identity and txid, prevents replay. An empty nonce means the signature header was not populated properly and the transaction would be invalid on the network.
Source
Thrown at core/tx/endorser/parser.go:141
Nonce: txenv.SignatureHeader.Nonce,
}, nil
}
func (e *EndorserTx) validate() error {
if e.Epoch != 0 {
return errors.Errorf("invalid epoch in ChannelHeader. Expected 0, got [%d]", e.Epoch)
}
if e.Version != 0 {
return errors.Errorf("invalid version in ChannelHeader. Expected 0, got [%d]", e.Version)
}
if err := ValidateChannelID(e.ChannelID); err != nil {
return err
}
if len(e.Nonce) == 0 {
return errors.New("empty nonce")
}
if len(e.Creator) == 0 {
return errors.New("empty creator")
}
if e.ChaincodeID == nil {
return errors.New("nil ChaincodeId")
}
if e.ChaincodeID.Name == "" {
return errors.New("empty chaincode name in chaincode id")
}
// TODO FAB-16170: check proposal hash
// TODO FAB-16170: verify that txid matches the one in the header
View on GitHub (pinned to 2736b63f8f)
Solutions
- Generate a fresh nonce with util.GetRandomNonce() and set SignatureHeader.Nonce when building the transaction.
- Ensure each transaction uses a NEW nonce — never reuse or blank it for retried submits.
- Verify the code path that serializes the SignatureHeader preserves the nonce bytes.
Example fix
// before
sh := &common.SignatureHeader{Creator: creator} // nonce missing
// after
sh := &common.SignatureHeader{Creator: creator, Nonce: util.GetRandomNonce()} Defensive patterns
Strategy: validation
Validate before calling
func hasNonce(sh *common.SignatureHeader) bool {
return len(sh.GetNonce()) > 0
}
// before submit: if !hasNonce(sigHeader) { sigHeader.Nonce = util.GetRandomNonce() } Type guard
func noncePresent(sh *common.SignatureHeader) bool {
return sh != nil && len(sh.Nonce) > 0
} Try / catch
tx, err := parser.UnmarshalEndorserTxAndValidate(env)
if err != nil {
if strings.Contains(err.Error(), "empty nonce") {
// signature header built without nonce: regenerate tx with a fresh nonce
return ErrInvalidHeader
}
return err
} Prevention
- Always set SignatureHeader.Nonce via util.GetRandomNonce().
- Never reuse a nonce across transactions; generate a fresh one per submit.
- Verify the header survives serialization without dropping the nonce field.
When it happens
Trigger: UnmarshalEndorserTxAndValidate is given an envelope whose SignatureHeader.Nonce is a zero-length byte slice — the header was built without generating/util.GetRandomNonce, or the nonce was dropped during assembly.
Common situations: Custom transaction assembly forgetting util.GetRandomNonce(); caching/reusing header structs and overwriting nonce with nil; SDK misconfiguration in the transaction-generation pipeline.
Related errors
- nil SignatureHeader provided
- invalid nonce specified in the header
- invalid creator specified in the header
- '%s' not equal <newest|oldest|config|(number)>
- unmarshalling block: %s
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/e10a85d50be61807.
Report an issue: GitHub.