hyperledger/fabric · error

depspec cannot be nil if buf is not nil

Error message

depspec cannot be nil if buf is not nil

What it means

PutChaincodeToFS requires ccpack.depSpec, the deserialized ChaincodeDeploymentSpec, to extract the chaincode name and version when writing the package file. buf being non-nil while depSpec is nil indicates the package bytes were loaded but never unmarshaled, so serialization to the filesystem is aborted.

Source

Thrown at core/common/ccprovider/cdspackage.go:236

}

// InitFromFS returns the chaincode and its package from the file system
func (ccpack *CDSPackage) InitFromFS(ccNameVersion string) ([]byte, *pb.ChaincodeDeploymentSpec, error) {
	return ccpack.InitFromPath(ccNameVersion, chaincodeInstallPath)
}

// PutChaincodeToFS - serializes chaincode to a package on the file system
func (ccpack *CDSPackage) PutChaincodeToFS() error {
	if ccpack.buf == nil {
		return errors.New("uninitialized package")
	}

	if ccpack.id == nil {
		return errors.New("id cannot be nil if buf is not nil")
	}

	if ccpack.depSpec == nil {
		return errors.New("depspec cannot be nil if buf is not nil")
	}

	if ccpack.data == nil {
		return errors.New("nil data")
	}

	if ccpack.datab == nil {
		return errors.New("nil data bytes")
	}

	ccname := ccpack.depSpec.ChaincodeSpec.ChaincodeId.Name
	ccversion := ccpack.depSpec.ChaincodeSpec.ChaincodeId.Version

	// return error if chaincode exists
	path := fmt.Sprintf("%s/%s.%s", chaincodeInstallPath, ccname, ccversion)
	if _, err := os.Stat(path); err == nil {
		return fmt.Errorf("chaincode %s exists", path)
	}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Re-initialize the package with InitFromBuffer(buf), which unmarshals the ChaincodeDeploymentSpec into ccpack.depSpec.
  2. Prefer InitFromPath + PutChaincodeToFS (or ccprovider.PutChaincode) over manual field population.
  3. Check and handle the error from any prior init call that may have stopped before depSpec was set.

Example fix

// before
ccpack := &CDSPackage{buf: buf, id: id} // depSpec missing
ccpack.PutChaincodeToFS()

// after
ccpack := &CDSPackage{}
if err := ccpack.InitFromBuffer(buf); err != nil {
    return err
}
ccpack.PutChaincodeToFS()
Defensive patterns

Strategy: validation

Validate before calling

if ccpack.buf != nil && ccpack.depSpec == nil {
    return errors.New("depspec not deserialized: call InitFromBuffer(buf) before writing")
}

Type guard

func hasDepSpec(p *ccprovider.CDSPackage) bool {
    return p != nil && p.buf != nil && p.depSpec != nil
}

Try / catch

if err := ccpack.PutChaincodeToFS(); err != nil {
    if strings.Contains(err.Error(), "depspec cannot be nil") {
        if e := ccpack.InitFromBuffer(ccpack.buf); e != nil {
            return e
        }
        return ccpack.PutChaincodeToFS()
    }
    return err
}

Prevention

When it happens

Trigger: Setting ccpack.buf without running the deserialization step (InitFromBuffer/InitFromPath/PutChaincodeDepSpec with proto unmarshal); a package struct assembled from a cache or copied across goroutines where only buf was carried over.

Common situations: Custom install code that caches raw bytes and reconstructs a CDSPackage with only buf; a corrupted or truncated init path that set buf but errored before unmarshaling the depspec, with the error ignored.

Related errors


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