hyperledger/fabric · error

could not unmarshal chaincode package to CDS or SignedCDS

Error message

could not unmarshal chaincode package to CDS or SignedCDS

What it means

GetCCPackage attempts to decode a chaincode package buffer first as ChaincodeDeploymentSpec (CDS) and then as SignedChaincodeDeploymentSpec (SignedCDS). If neither protobuf unmarshal succeeds, it concludes the bytes are not a recognizable chaincode package and returns this error.

Source

Thrown at core/common/ccprovider/ccprovider.go:296

		}
	}

	if cds != nil && scds != nil {
		// Both were unmarshaled successfully, this is exactly why the approach of
		// hoping proto fails for bad inputs is fatally flawed.
		ccproviderLogger.Errorf("Could not determine chaincode package type, guessing SignedCDS")
		return scds, nil
	}

	if cds != nil {
		return cds, nil
	}

	if scds != nil {
		return scds, nil
	}

	return nil, errors.New("could not unmarshal chaincode package to CDS or SignedCDS")
}

// GetInstalledChaincodes returns a map whose key is the chaincode id and
// value is the ChaincodeDeploymentSpec struct for that chaincodes that have
// been installed (but not necessarily instantiated) on the peer by searching
// the chaincode install path
func GetInstalledChaincodes() (*pb.ChaincodeQueryResponse, error) {
	files, err := os.ReadDir(chaincodeInstallPath)
	if err != nil {
		return nil, err
	}

	// array to store info for all chaincode entries from LSCC
	var ccInfoArray []*pb.ChaincodeInfo

	for _, file := range files {
		// split at first period as chaincode versions can contain periods while
		// chaincode names cannot

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Confirm you are passing raw CDS/SignedCDS protobuf bytes, not a tar package archive
  2. Regenerate the package with the matching Fabric SDK/version and retry
  3. Verify the buffer is not empty or truncated (check byte length before calling)
  4. Check for network/storage corruption if the bytes came from a transfer

Example fix

// before
ccpack, err := ccprovider.GetCCPackage(tarFileBytes, cifs.GetHasher) // wrong: tar archive
// after
ccpack, err := ccprovider.GetCCPackage(cdsBytes, cifs.GetHasher) // raw CDS protobuf bytes
Defensive patterns

Strategy: validation

Validate before calling

func isPlausibleCDS(buf []byte) bool {
    cds := &pb.ChaincodeDeploymentSpec{}
    return len(buf) > 0 && proto.Unmarshal(buf, cds) == nil && cds.ChaincodeSpec != nil
}

Type guard

func isCDSBuffer(buf []byte) bool {
    spec := &pb.ChaincodeDeploymentSpec{}
    return proto.Unmarshal(buf, spec) == nil && spec.ChaincodeSpec != nil && spec.ChaincodeSpec.ChaincodeId != nil
}

Try / catch

ccpack, err := ccprovider.GetCCPackage(buf, hasher)
if err != nil {
    if err.Error() == "could not unmarshal chaincode package to CDS or SignedCDS" {
        return fmt.Errorf("not a chaincode package (got %d bytes): %w", len(buf), err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling GetCCPackage with bytes that are neither a CDS nor a SignedCDS — empty buffer, random garbage, an already-tarred install package, or a package format from an incompatible Fabric version.

Common situations: Passing the .tar.gz file contents from 'peer chaincode package' directly instead of the packaged CDS bytes; uploading corrupted package over the network; mixing Fabric v1.x package formats across versions.

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/df450d48bd0fc725. Report an issue: GitHub.