{"record":{"id":"6b4e91be0bad7ef4","repo":"microsoft/garnet","slug":"invalid-clusterconfig-payload-too-short-to-contai","errorCode":null,"errorMessage":"Invalid ClusterConfig payload: too short to contain a version","messagePattern":"Invalid ClusterConfig payload: too short to contain a version","errorType":"exception","errorClass":"InvalidDataException","httpStatus":null,"severity":"error","filePath":"libs/cluster/Server/ClusterConfigSerializer.cs","lineNumber":134,"sourceCode":"\n            //Write segment count at the reserved position\n            var _position = ms.Position;\n            ms.Position = segmentCountPosition;\n            writer.Write(segmentCount);\n            ms.Position = _position;\n        }\n\n        /// <summary>\n        /// Deserialize config from byte array\n        /// </summary>\n        public static ClusterConfig FromByteArray(byte[] other)\n        {\n            var ms = new MemoryStream(other);\n            var reader = new BinaryReader(ms);\n\n            // Read and validate serialization format version\n            if (other.Length < 1)\n                throw new InvalidDataException(\"Invalid ClusterConfig payload: too short to contain a version\");\n            var version = reader.ReadByte();\n            if (version != ClusterConfigVersion)\n                throw new InvalidDataException($\"Incompatible ClusterConfig version: expected {ClusterConfigVersion}, got {version}\");\n\n            var newSlotMap = DeserializeSlotMap(ref reader);\n\n            int numWorkers = reader.ReadInt32();\n            var newWorkers = new Worker[numWorkers];\n            for (int i = 1; i < numWorkers; i++)\n            {\n                newWorkers[i].Nodeid = reader.ReadString();\n                newWorkers[i].Address = reader.ReadString();\n                newWorkers[i].Port = reader.ReadInt32();\n                newWorkers[i].ConfigEpoch = reader.ReadInt64();\n                newWorkers[i].Role = (NodeRole)reader.ReadByte();\n\n                byte isNull = reader.ReadByte();\n                if (isNull > 0)","sourceCodeStart":116,"sourceCodeEnd":152,"githubUrl":"https://github.com/microsoft/garnet/blob/951b0fc6838721f89d102c2bbe1b914e8d39d700/libs/cluster/Server/ClusterConfigSerializer.cs#L116-L152","documentation":"ClusterConfig.FromByteArray deserializes a cluster config from a byte payload and first checks that the array has at least one byte (the version byte). A zero-length payload is rejected as InvalidDataException because there is no version to read. This guards against truncated/corrupt gossip or replication messages carrying an empty config body.","triggerScenarios":"FromByteArray receives an empty byte[] (length 0) — e.g. a gossip/replication peer sent an empty or truncated config payload, a network read returned no bytes, or a corrupt/stale config was loaded from disk.","commonSituations":"Cluster nodes exchanging malformed gossip; a replication AOF/config file truncated to zero bytes; a serialization bug producing empty payloads; version skew where a peer sends an unexpected frame.","solutions":["Validate payload length before calling FromByteArray and skip/log empty messages.","Ensure gossip and replication channels deliver complete frames (check for partial reads/connection drops).","If loading from disk, verify the config file is non-empty and intact."],"exampleFix":"// before\nvar config = ClusterConfig.FromByteArray(payload);\n\n// after — guard empty payloads\nif (payload is null || payload.Length == 0) { logger?.LogWarning(\"empty cluster config payload\"); return; }\nvar config = ClusterConfig.FromByteArray(payload);","handlingStrategy":"validation","validationCode":"if (payload is null || payload.Length == 0) { logger?.LogWarning(\"empty cluster config payload\"); return; }\nvar config = ClusterConfig.FromByteArray(payload);","typeGuard":"bool IsValidConfigPayload(byte[] p) => p is not null && p.Length >= 1;","tryCatchPattern":"try { var config = ClusterConfig.FromByteArray(payload); }\ncatch (InvalidDataException ex) { logger?.LogWarning(ex, \"bad cluster config payload\"); /* skip/ignore */ }","preventionTips":["Validate payload length before deserializing.","Ensure gossip/replication channels deliver complete frames.","Verify persisted config files are non-empty and intact."],"tags":["csharp","cluster-config","deserialization","validation","cluster"],"backgroundTag":null,"analyzedSha":"951b0fc6838721f89d102c2bbe1b914e8d39d700","analyzedAt":"2026-08-13T19:01:32.939Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}