microsoft/garnet · critical · GarnetException

Type not supported {headerType}

Error message

Type not supported {headerType}

What it means

Thrown by AofHeader.SkipHeader(byte* entryPtr) when the 2-bit HeaderType field read from a raw AOF entry does not match any known AofHeaderType (BasicHeader=0, ShardedHeader=1, SingleLogTransactionHeader=2, ShardedLogTransactionHeader=3). Since the type field is only 2 bits, an unknown value implies memory corruption, a misaligned pointer, or reading non-AOF data as an AOF entry.

Source

Thrown at libs/server/AOF/AofHeader.cs:137

    };

    /// <summary>
    /// Basic AOF header
    /// </summary>
    [StructLayout(LayoutKind.Explicit, Size = TotalSize)]
    struct AofHeader
    {
        public static unsafe byte* SkipHeader(byte* entryPtr)
        {
            var header = *(AofHeader*)entryPtr;
            var headerType = header.HeaderType;
            return headerType switch
            {
                AofHeaderType.BasicHeader => entryPtr + TotalSize,
                AofHeaderType.ShardedHeader => entryPtr + AofShardedHeader.TotalSize,
                AofHeaderType.ShardedLogTransactionHeader => entryPtr + AofShardedLogTransactionHeader.TotalSize,
                AofHeaderType.SingleLogTransactionHeader => entryPtr + AofSingleLogTransactionHeader.TotalSize,
                _ => throw new GarnetException($"Type not supported {headerType}"),
            };
        }

        public const int TotalSize = 16;

        // Important: Update AofHeaderVersion whenever any of the following change:
        // * Layout, size, contents of this struct
        // * Any of the AofEntryType or AofStoreType enums' existing value mappings
        // * SpanByte format or header
        // * The persisted-value numbering of any enum serialized into an entry payload:
        //   RespCommand (RespInputHeader.cmd), the object sub-operation enums (RespInputHeader.SubId:
        //   HashOperation/ListOperation/SetOperation/SortedSetOperation), GarnetObjectType
        //   (RespInputHeader.type), or RespInputFlags.
        // * The layout of RespInputHeader itself (e.g. which byte holds cmd/type/subId/flags).
        // Version 3 repurposes the flags byte as a bitfield containing the header type
        // plus chunked-record and unsafe-truncate markers.
        // Version 4 makes the RespCommand write block dense/explicit (writes-first) and moves the
        // object sub-operation id (SubId) from the low 5 bits of the flags byte into its own header

View on GitHub (pinned to 951b0fc683)

Solutions

  1. Verify the AOF data was produced by a compatible Garnet build (same struct layout, same AofHeaderVersion).
  2. Check for disk/memory corruption — run on a clean checkpoint and AOF, or restore from backup.
  3. If the data is from an older build, use the matching Garnet version to replay it rather than a mismatched build.
  4. Investigate the caller: ensure the pointer is aligned to a real AOF entry boundary.
Defensive patterns

Strategy: try-catch

Try / catch

try { ptr = AofHeader.SkipHeader(ptr); }
catch (GarnetException ex)
{
    logger.LogCritical(ex, "AOF header type {Type} unrecognized at offset {Offset}", header.HeaderType, offset);
    // halt recovery; do not continue scanning past corruption
    throw;
}

Prevention

When it happens

Trigger: SkipHeader is called with a pointer that doesn't actually point at a valid AofHeader — for example, a corrupted log entry, an address past the end of valid data, or data from a different store layout. The switch exhausts all four legal enum values, so any other bit pattern hits the default.

Common situations: AOF file or memory page corruption; a Garnet downgrade or layout mismatch where the on-disk struct layout differs from what this build expects; a bug causing an incorrect pointer arithmetic before calling SkipHeader.

Related errors


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