hyperledger/fabric · error
chaincode input did not contain any input
Error message
chaincode input did not contain any input
What it means
The ChaincodeInvocationSpec decoded from the proposal payload exists and has a ChaincodeSpec, but ChaincodeSpec.Input is nil. Input holds the function name and args to pass to the chaincode, so a proposal without it is not executable. The endorser rejects the proposal before any chaincode runs.
Source
Thrown at core/endorser/msgvalidation.go:91
return nil, errors.Errorf("ChaincodeHeaderExtension.ChaincodeId.Name is empty")
}
cpp, err := protoutil.UnmarshalChaincodeProposalPayload(prop.Payload)
if err != nil {
return nil, err
}
cis, err := protoutil.UnmarshalChaincodeInvocationSpec(cpp.Input)
if err != nil {
return nil, err
}
if cis.ChaincodeSpec == nil {
return nil, errors.Errorf("chaincode invocation spec did not contain chaincode spec")
}
if cis.ChaincodeSpec.Input == nil {
return nil, errors.Errorf("chaincode input did not contain any input")
}
cppNoTransient := &peer.ChaincodeProposalPayload{Input: cpp.Input, TransientMap: nil}
ppBytes, err := proto.Marshal(cppNoTransient)
if err != nil {
return nil, errors.WithMessage(err, "could not marshal non-transient portion of payload")
}
// TODO, this was preserved from the proputils stuff, but should this be BCCSP?
// The proposal hash is the hash of the concatenation of:
// 1) The serialized Channel Header object
// 2) The serialized Signature Header object
// 3) The hash of the part of the chaincode proposal payload that will go to the tx
// (ie, the parts without the transient data)
propHash := sha256.New()
propHash.Write(hdr.ChannelHeader)
propHash.Write(hdr.SignatureHeader)View on GitHub (pinned to 2736b63f8f)
Solutions
- Always populate ChaincodeSpec.Input with at least the function name and args (ChaincodeInput.Args) before signing the proposal.
- Check the SDK client call passes a non-empty function/args list (e.g. contract.submitTransaction('fn', ...args)).
- If using transient/private data flows, ensure the input is in the proposal, not moved entirely into the transient map.
Example fix
// before
spec := &pb.ChaincodeSpec{ChaincodeId: &pb.ChaincodeID{Name: "mycc"}}
// after
spec := &pb.ChaincodeSpec{
ChaincodeId: &pb.ChaincodeID{Name: "mycc"},
Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("invoke"), []byte("a"), []byte("b"), []byte("1")}},
} Defensive patterns
Strategy: validation
Validate before calling
if cis.ChaincodeSpec == nil || cis.ChaincodeSpec.Input == nil || len(cis.ChaincodeSpec.Input.Args) == 0 {
return errors.New("chaincode input/args required")
} Type guard
func hasChaincodeInput(spec *pb.ChaincodeSpec) bool {
return spec != nil && spec.Input != nil && len(spec.Input.Args) > 0
} Prevention
- Require function name and args in your submit wrapper API
- Validate args before marshaling the proposal
- Never build ChaincodeSpec without Input
When it happens
Trigger: ProcessProposal -> UnpackProposal receives a SignedProposal whose ChaincodeSpec was populated with ChaincodeId and Type but with Input left nil — e.g. building a query/invoke with no args, or a deploy-type spec without constructor args.
Common situations: SDK calls where the 'args' or 'fcn' parameter was omitted/empty, manually constructed ChaincodeSpec protobufs, chaincode upgrade/install proposals stripped of input during custom tooling transformations.
Related errors
- chaincode invocation spec did not contain chaincode spec
- empty proposal bytes
- ChaincodeHeaderExtension.ChaincodeId is nil
- ChaincodeHeaderExtension.ChaincodeId.Name is empty
- invalid header type %s
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/6f3dfe49cfab3c4b.
Report an issue: GitHub.