hyperledger/fabric · error
at least one proposal response is required
Error message
at least one proposal response is required
What it means
CreateSignedTx requires at least one endorsed *peer.ProposalResponse to assemble a transaction envelope. Called with zero variadic resps, it returns this error because a transaction cannot be built without an endorsement to attach.
Source
Thrown at protoutil/txutils.go:144
}
// Signer is the interface needed to sign a transaction
type Signer interface {
Sign(msg []byte) ([]byte, error)
Serialize() ([]byte, error)
}
// CreateSignedTx assembles an Envelope message from proposal, endorsements,
// and a signer. This function should be called by a client when it has
// collected enough endorsements for a proposal to create a transaction and
// submit it to peers for ordering
func CreateSignedTx(
proposal *peer.Proposal,
signer Signer,
resps ...*peer.ProposalResponse,
) (*common.Envelope, error) {
if len(resps) == 0 {
return nil, errors.New("at least one proposal response is required")
}
if signer == nil {
return nil, errors.New("signer is required when creating a signed transaction")
}
// the original header
hdr, err := UnmarshalHeader(proposal.Header)
if err != nil {
return nil, err
}
// the original payload
pPayl, err := UnmarshalChaincodeProposalPayload(proposal.Payload)
if err != nil {
return nil, err
}
View on GitHub (pinned to 2736b63f8f)
Solutions
- Collect at least one successful ProposalResponse from the endorsers before calling CreateSignedTx
- Check endorser connectivity/errors when the responses slice is empty and surface that root cause
- For multi-endorsement policies, gather responses meeting the policy instead of attempting with none
- Spread slices with resps... rather than passing the slice itself
Example fix
// before
env, err := protoutil.CreateSignedTx(proposal, signer) // no responses
// after
if len(resps) == 0 {
return nil, fmt.Errorf("no endorsement responses collected: %w", collectErr)
}
env, err := protoutil.CreateSignedTx(proposal, signer, resps...) Defensive patterns
Strategy: validation
Validate before calling
func requireResponses(resps []*peer.ProposalResponse) error {
if len(resps) == 0 {
return fmt.Errorf("no proposal responses: check endorser errors")
}
return nil
} Type guard
func hasEndorsements(resps []*peer.ProposalResponse) bool {
return len(resps) > 0
} Try / catch
if err := requireResponses(resps); err != nil {
return nil, err
}
tx, err := protoutil.CreateSignedTx(proposal, signer, resps...)
if err != nil {
return nil, fmt.Errorf("create tx: %w", err)
} Prevention
- Fail fast when an endorsement round yields zero responses and report the endorser errors
- Spread slices with resps... in variadic calls
- Track endorser failures so empty response sets are diagnosable
When it happens
Trigger: Calling CreateSignedTx(proposal, signer) with no variadic arguments, or with a slice of responses spread incorrectly (e.g. passing a nil slice rather than resps...).
Common situations: An endorsement round that returned zero responses (all endorsers failed/timed out) and the caller proceeds to assemble the tx anyway; SDK code that drops failed responses and ends up with an empty list.
Related errors
- no endorsements
- failed to execute transaction %s
- timeout expired while executing transaction
- chaincode definition for '%s' exists, but chaincode is not i
- could not get channel config for channel '%s'
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/edd2991d6f33599a.
Report an issue: GitHub.