hyperledger/fabric · error
nil data bytes
Error message
nil data bytes
What it means
ccpack.datab is the serialized bytes of the ChaincodeData (data marshaled to protobuf). PutChaincodeToFS checks it last before writing: buf/id/depSpec/data all present but datab nil means the final marshal step never ran, so the on-disk package would be incomplete and the write is refused.
Source
Thrown at core/common/ccprovider/cdspackage.go:244
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)
}
if err := os.WriteFile(path, ccpack.buf, 0o644); err != nil {
return err
}
return nil
}
View on GitHub (pinned to 2736b63f8f)
Solutions
- Initialize via InitFromBuffer/InitFromPath, which marshal ChaincodeData into datab, then call PutChaincodeToFS.
- If manual, marshal the data yourself: datab, err := proto.Marshal(ccpack.data); check err and assign ccpack.datab before writing.
- Stop hand-assembling CDSPackage and route through ccprovider.PutChaincode / processCDS which guarantee full population.
Example fix
// before
ccpack.data = ccdata // datab never marshaled
ccpack.PutChaincodeToFS()
// after
datab, err := proto.Marshal(ccdata)
if err != nil {
return err
}
ccpack.datab = datab
ccpack.PutChaincodeToFS() Defensive patterns
Strategy: validation
Validate before calling
if ccpack.buf != nil && ccpack.datab == nil {
return errors.New("ChaincodeData bytes missing: data must be marshaled before PutChaincodeToFS")
} Type guard
func hasDataBytes(p *ccprovider.CDSPackage) bool {
return p != nil && p.buf != nil && p.datab != nil
} Try / catch
if err := ccpack.PutChaincodeToFS(); err != nil {
if err.Error() == "nil data bytes" {
return fmt.Errorf("package serialization incomplete: %w", err)
}
return err
} Prevention
- Use the library's init functions so the proto.Marshal(data) -> datab step is never skipped.
- When deep-copying packages, ensure byte slices (buf, datab) are carried over or regenerated.
- Verify package completeness (buf, id, depSpec, data, datab all non-nil) before any write path.
When it happens
Trigger: A CDSPackage populated through custom code that set data but never serialized it to datab (proto.Marshal step in InitFromBuffer/PutChaincodeDepSpec skipped or its error ignored).
Common situations: Reimplementing package initialization in forked code and missing the datab = proto.Marshal(data) step; a marshal failure swallowed earlier; deep-copying a package and dropping the bytes field; test fixtures missing one field.
Related errors
- id cannot be nil if buf is not nil
- depspec cannot be nil if buf is not nil
- Value of File: was nil
- First message needs to be a register
- TLS is active but chaincode %s didn't send certificate
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/ac54b62e7e0ea851.
Report an issue: GitHub.