microsoft/garnet · critical · GarnetException

Unsupported object serialization format marker 0x{firstByte:

Error message

Unsupported object serialization format marker 0x{firstByte:X2}; the data may have been written by a newer Garnet version.

What it means

Thrown by GarnetObjectSerializer.Deserialize when the first byte of a serialized object is >= 0xFC (ReservedObjectFormatByteStart). Bytes 0xFC-0xFF are reserved for a future versioned/escape format that no current writer emits, so encountering one means the record was written by a newer Garnet whose object format this build cannot read. It is a deliberate, fail-fast data-compatibility guard.

Source

Thrown at libs/server/Objects/Types/GarnetObjectSerializer.cs:60

        /// <returns></returns>
        public IGarnetObject Deserialize(byte[] data)
        {
            Debug.Assert(data != null);

            using var ms = new MemoryStream(data);
            using var binaryReader = new BinaryReader(ms, Encoding.UTF8);
            return DeserializeInternal(binaryReader);
        }

        private IGarnetObject DeserializeInternal(BinaryReader binaryReader)
        {
            var firstByte = binaryReader.ReadByte();

            // 0xFC..0xFF are reserved for a future object-serialization format version/escape byte
            // (see GarnetObjectType). No current writer emits these, so encountering one means the
            // data was written by a newer version whose object format this build cannot read.
            if (firstByte >= GarnetObjectTypeExtensions.ReservedObjectFormatByteStart)
                throw new GarnetException($"Unsupported object serialization format marker 0x{firstByte:X2}; the data may have been written by a newer Garnet version.");

            var type = (GarnetObjectType)firstByte;
            var obj = type switch
            {
                GarnetObjectType.Null => null,
                GarnetObjectType.SortedSet => new SortedSetObject(binaryReader),
                GarnetObjectType.List => new ListObject(binaryReader),
                GarnetObjectType.Hash => new HashObject(binaryReader),
                GarnetObjectType.Set => new SetObject(binaryReader),
                _ => CustomDeserialize((byte)type, binaryReader),
            };
            return obj;
        }

        private IGarnetObject CustomDeserialize(byte type, BinaryReader binaryReader)
        {
            // Built-in type ids (0..LastObjectType) are handled by the caller. A type id below the
            // fixed custom-object base therefore lies in the reserved built-in band and is not valid

View on GitHub (pinned to 951b0fc683)

Solutions

  1. Do not downgrade Garnet across a version that introduced a new object-format escape byte; upgrade the reading node instead.
  2. If you must move data, export it via RESP (DUMP/RESTORE or replication) rather than reusing on-disk object files across incompatible versions.
  3. Confirm the build reading the data is at least as new as the build that wrote it.
Defensive patterns

Strategy: validation

Validate before calling

// Before recovering from a checkpoint/object log, assert build compatibility
if (dataFormatByte >= 0xFC)
    throw new InvalidOperationException("Refusing data from a newer Garnet object format (reserved leading byte).");

Try / catch

catch (GarnetException ex) when (ex.Message.Contains("Unsupported object serialization format marker")) {
    logger.LogCritical("On-disk object format is newer than this build; upgrade Garnet before recovering.");
    throw;
}

Prevention

When it happens

Trigger: Reading a checkpoint, AOF, or object log (object-store recovery) where the persisted object's leading byte is in the reserved band - i.e., the data was produced by a newer Garnet.

Common situations: Downgrading Garnet to an older version against data/checkpoints written by a newer version; loading a snapshot from a different Garnet edition.

Related errors


AI-assisted analysis of microsoft/garnet@951b0fc683 (2026-08-13). Data as JSON: /api/errors/a0def6e2fc2c2416. Report an issue: GitHub.