hyperledger/fabric · error

chaincode %s has bad definition

Error message

chaincode %s has bad definition

What it means

ChaincodeEndorsementInfo raises this when the bytes stored under the chaincode name in lscc state exist but fail proto.Unmarshal into ccprovider.ChaincodeData — i.e. the chaincode definition on the ledger is malformed ('bad definition'). The wrapped error identifies the protobuf decode failure.

Source

Thrown at core/scc/lscc/lscc.go:268

	}

	return nil
}

func (lscc *SCC) ChaincodeEndorsementInfo(channelID, chaincodeName string, qe ledger.SimpleQueryExecutor) (*lifecycle.ChaincodeEndorsementInfo, error) {
	chaincodeDataBytes, err := qe.GetState("lscc", chaincodeName)
	if err != nil {
		return nil, errors.Wrapf(err, "could not retrieve state for chaincode %s", chaincodeName)
	}

	if chaincodeDataBytes == nil {
		return nil, errors.Errorf("chaincode %s not found", chaincodeName)
	}

	chaincodeData := &ccprovider.ChaincodeData{}
	err = proto.Unmarshal(chaincodeDataBytes, chaincodeData)
	if err != nil {
		return nil, errors.Wrapf(err, "chaincode %s has bad definition", chaincodeName)
	}

	ls := &LegacySecurity{
		Support:      lscc.Support,
		PackageCache: &lscc.PackageCache,
	}

	err = ls.SecurityCheckLegacyChaincode(chaincodeData)
	if err != nil {
		return nil, errors.WithMessage(err, "failed security checks")
	}

	return &lifecycle.ChaincodeEndorsementInfo{
		Version:           chaincodeData.Version,
		EndorsementPlugin: chaincodeData.Escc,
		ChaincodeID:       chaincodeData.Name + ":" + chaincodeData.Version,
	}, nil
}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Read the wrapped proto error to identify the malformed field
  2. Re-approve/re-commit (or re-instantiate in legacy flow) the chaincode definition so valid ChaincodeData is written
  3. Restore lscc state from a consistent backup or rebuild the state DB
  4. Check Fabric version compatibility between the data and the running peer
Defensive patterns

Strategy: validation

Validate before calling

// Go: sanity-decode ChaincodeData before trusting the definition
raw, err := qe.GetState("lscc", chaincodeName)
if err != nil || raw == nil { return err }
data := &ccprovider.ChaincodeData{}
if err := proto.Unmarshal(raw, data); err != nil {
    return fmt.Errorf("definition for %s is corrupt: %w", chaincodeName, err)
}
if data.GetName() == "" || data.GetVersion() == "" {
    return fmt.Errorf("definition for %s missing required fields", chaincodeName)
}

Try / catch

// Go
info, err := lscc.ChaincodeEndorsementInfo(channelID, name, qe)
if err != nil && strings.Contains(err.Error(), "has bad definition") {
    return fmt.Errorf("corrupt ChaincodeData for %s; re-approve/re-commit the definition: %w", name, err)
}

Prevention

When it happens

Trigger: Calling ChaincodeEndorsementInfo where GetState("lscc", chaincodeName) returns non-nil bytes that cannot be decoded as ChaincodeData.

Common situations: Corrupted lscc state entries; definitions written by an incompatible Fabric version (schema drift); ledger restores/hand-edits that left invalid ChaincodeData under the lscc key.

Understand the failure class

Background: "cannot parse invalid wire-format data", "cannot unmarshal", "failed unmarshalling": protobuf unmarshal errors explained — this error's family across 10 libraries.

Related errors


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