{"record":{"id":"eeac5bf5b3403f4b","repo":"hyperledger/fabric","slug":"error-marshalling-proto-message-to-write-to-the-sn","errorCode":null,"errorMessage":"error marshalling proto message to write to the snapshot file: %s: proto: Marshal called with nil","messagePattern":"error marshalling proto message to write to the snapshot file: (.+?): proto: Marshal called with nil","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/ledger/snapshot/file.go","lineNumber":70,"sourceCode":"\t}\n\treturn &FileWriter{\n\t\tfile:              file,\n\t\tbufWriter:         bufWriter,\n\t\tmultiWriter:       multiWriter,\n\t\thasher:            hashImpl,\n\t\tvarintReusableBuf: make([]byte, binary.MaxVarintLen64),\n\t}, nil\n}\n\n// EncodeString encodes and appends the string to the data stream\nfunc (c *FileWriter) EncodeString(str string) error {\n\treturn c.EncodeBytes([]byte(str))\n}\n\n// EncodeProtoMessage encodes and appends a proto message to the data stream\nfunc (c *FileWriter) EncodeProtoMessage(m proto.Message) error {\n\tif m == nil || !m.ProtoReflect().IsValid() {\n\t\treturn errors.Errorf(\"error marshalling proto message to write to the snapshot file: %s: proto: Marshal called with nil\", c.file.Name())\n\t}\n\tb, err := proto.Marshal(m)\n\tif err != nil {\n\t\treturn errors.Wrapf(err, \"error marshalling proto message to write to the snapshot file: %s\", c.file.Name())\n\t}\n\treturn c.EncodeBytes(b)\n}\n\n// EncodeBytes encodes and appends bytes to the data stream\nfunc (c *FileWriter) EncodeBytes(b []byte) error {\n\tif err := c.EncodeUVarint(uint64(len(b))); err != nil {\n\t\treturn err\n\t}\n\tif _, err := c.multiWriter.Write(b); err != nil {\n\t\treturn errors.Wrapf(err, \"error while writing data to the snapshot file: %s\", c.file.Name())\n\t}\n\treturn nil\n}","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/common/ledger/snapshot/file.go#L52-L88","documentation":"FileWriter.EncodeProtoMessage refuses to encode a proto message that is nil or invalid before calling proto.Marshal, because protobuf's Marshal panics/errs with 'proto: Marshal called with nil' in that case. The error wraps the snapshot file name so the developer knows which snapshot was being written. It indicates the caller (AddData or the ledger export path) passed an unset/invalid protobuf message into the snapshot encoder.","triggerScenarios":"Calling AddData/EncodeProtoMessage with a nil proto.Message, or with a typed-nil pointer (e.g. (*pb.SomeMsg)(nil)) whose ProtoReflect().IsValid() is false.","commonSituations":"Exporting a ledger snapshot where a config or collection record is missing/nil (e.g. empty collection config, unset config history entry), or a lookup returned nil and the code passed it straight to the snapshot writer.","solutions":["Check the proto message for nil/invalid before calling AddData and skip or substitute a valid message","Fix the upstream producer so it never yields a nil message (e.g. return an explicit error when a record is absent)","Log which field/key produced the nil message to locate the corrupt or missing ledger data"],"exampleFix":"// before\nif err := w.AddData(key, someMsg); err != nil { ... }\n// after\nif someMsg == nil || !someMsg.ProtoReflect().IsValid() {\n    return errors.New(\"skipping nil proto message for key \" + string(key))\n}\nif err := w.AddData(key, someMsg); err != nil { ... }","handlingStrategy":"validation","validationCode":"func validProto(m proto.Message) bool { return m != nil && m.ProtoReflect().IsValid() }\n// call: if !validProto(msg) { return errors.New(\"nil proto message\") }","typeGuard":"func isNilProto(m proto.Message) bool {\n    return m == nil || !m.ProtoReflect().IsValid()\n}","tryCatchPattern":"if err := w.AddData(k, msg); err != nil {\n    if strings.Contains(err.Error(), \"Marshal called with nil\") {\n        log.Warnf(\"skipping nil message for key %s\", k); return nil\n    }\n    return err\n}","preventionTips":["Never pass typed-nil proto pointers to AddData","Check m.ProtoReflect().IsValid() before encoding","Ensure producers of config/collection records return explicit errors instead of nil messages"],"tags":["protobuf","snapshot","nil-pointer","ledger"],"backgroundTag":"proto-marshal-called-with-nil","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}