SixLabors/ImageSharp · error · ArgumentException

Must be bytes. Was bytes.

Error message

Must be {SizeV5} bytes. Was {data.Length} bytes.

What it means

BmpInfoHeader.ParseV5 reinterprets the input byte span as a BmpInfoHeader structure, which requires at least SizeV5 bytes. If the provided span is shorter, it throws ArgumentException naming the 'data' parameter with the required and actual lengths — the caller passed a buffer smaller than a BITMAPV5HEADER.

Solutions

  1. Read the header's declared size first and only call ParseV5 when the available span length >= BmpInfoHeader.SizeV5.
  2. Pad/extend the buffer from the stream to at least SizeV5 bytes before parsing.
  3. Use the decoder's public API instead of parsing the header span manually.

Example fix

// before
var header = BmpInfoHeader.ParseV5(data[14..]); // may be < SizeV5
// after
if (data.Length - 14 >= BmpInfoHeader.SizeV5)
    var header = BmpInfoHeader.ParseV5(data[14..]);
Defensive patterns

Strategy: type-guard

Validate before calling

if (span.Length < BmpInfoHeader.SizeV5) throw new ArgumentException("Header buffer too short for V5.");

Type guard

static bool IsV5HeaderPresent(ReadOnlySpan<byte> data) => data.Length >= 14 + BmpInfoHeader.SizeV5;

Try / catch

try { var h = BmpInfoHeader.ParseV5(data); }
catch (ArgumentException ex) { /* read declared header size and re-slice buffer */ }

Prevention

When it happens

Trigger: Calling BmpInfoHeader.ParseV5 directly with a span sliced from a shorter header (e.g. a 40-byte BITMAPINFOHEADER region) or from a truncated file whose V5 header size field doesn't match available bytes.

Common situations: Custom metadata parsers reading V5 headers from truncated BMPs; code assuming SizeV5 bytes are always present after the file header.

Related errors


AI-assisted analysis of SixLabors/ImageSharp@59ce6af6fc (2026-09-13). Data as JSON: /api/errors/6dceb35a931e5b78. Report an issue: GitHub.

Appendix: source

Thrown at src/ImageSharp/Formats/Bmp/BmpInfoHeader.cs:470

        blueX: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(84, 4)),
        blueY: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(88, 4)),
        blueZ: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(92, 4)),
        gammeRed: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(96, 4)),
        gammeGreen: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(100, 4)),
        gammeBlue: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(104, 4)));

    /// <summary>
    /// Parses the full BMP Version 5 BITMAPINFOHEADER header (124 bytes).
    /// </summary>
    /// <param name="data">The data to parse.</param>
    /// <returns>The parsed header.</returns>
    /// <seealso href="https://docs.microsoft.com/de-de/windows/win32/api/wingdi/ns-wingdi-bitmapv5header?redirectedfrom=MSDN"/>
    /// <exception cref="ArgumentException">Invalid size.</exception>
    public static BmpInfoHeader ParseV5(ReadOnlySpan<byte> data)
    {
        if (data.Length < SizeV5)
        {
            throw new ArgumentException($"Must be {SizeV5} bytes. Was {data.Length} bytes.", nameof(data));
        }

        return MemoryMarshal.Cast<byte, BmpInfoHeader>(data)[0];
    }

    /// <summary>
    /// Writes a bitmap version 3 (Microsoft Windows NT) header to a buffer (40 bytes).
    /// </summary>
    /// <param name="buffer">The buffer to write to.</param>
    public void WriteV3Header(Span<byte> buffer)
    {
        buffer.Clear();
        BinaryPrimitives.WriteInt32LittleEndian(buffer[..4], SizeV3);
        BinaryPrimitives.WriteInt32LittleEndian(buffer.Slice(4, 4), this.Width);
        BinaryPrimitives.WriteInt32LittleEndian(buffer.Slice(8, 4), this.Height);
        BinaryPrimitives.WriteInt16LittleEndian(buffer.Slice(12, 2), this.Planes);
        BinaryPrimitives.WriteUInt16LittleEndian(buffer.Slice(14, 2), this.BitsPerPixel);
        BinaryPrimitives.WriteInt32LittleEndian(buffer.Slice(16, 4), (int)this.Compression);

View on GitHub (pinned to 59ce6af6fc)