SixLabors/ImageSharp · error · InvalidImageContentException

The icon directory contains an invalid image resource range.

Error message

The icon directory contains an invalid image resource range.

What it means

Thrown in SetFrameStreamBounds when a directory entry violates resource-range invariants: Reserved is nonzero, BytesInRes is zero, or ImageOffset points into the directory itself or at/beyond the end of the containing stream. SixLabors.ImageSharp throws InvalidImageContentException because the entry cannot designate a valid embedded image payload.

Solutions

  1. Verify each entry: ImageOffset must be >= 6 + 16*Count and ImageOffset + BytesInRes must fit within the file
  2. Re-export the icon with a reliable tool
  3. Catch InvalidImageContentException and reject/treat the file as corrupt
  4. If you generate ICO files, compute offsets from actual written payload positions, not estimates

Example fix

// before
var image = Image.Load("suspicious.ico");
// after
try
{
    var image = Image.Load("suspicious.ico");
}
catch (InvalidImageContentException)
{
    // directory entry points outside the icon resource
    throw new InvalidOperationException("Corrupt ICO directory entry");
}
Defensive patterns

Strategy: try-catch

Validate before calling

// each entry must satisfy: ImageOffset >= 6 + 16*count and ImageOffset + BytesInRes <= fileLength
static bool EntryRangeIsValid(ReadOnlySpan<byte> ico)
{
    ushort count = (ushort)(ico[4] | (ico[5] << 8));
    for (int i = 0; i < count; i++)
    {
        int e = 6 + 16 * i;
        uint offset = BitConverter.ToUInt32(ico.Slice(e + 12, 4));
        uint size = BitConverter.ToUInt32(ico.Slice(e + 8, 4));
        if (size == 0 || offset < 6 + 16L * count || offset + size > (uint)ico.Length) return false;
    }
    return true;
}

Type guard

static bool IsInvalidImageContent(Exception ex) => ex is InvalidImageContentException;

Try / catch

try
{
    var image = Image.Load(icoStream);
}
catch (InvalidImageContentException)
{
    // entry points outside the icon resource
    RejectCorruptIcon(icoPath);
}

Prevention

When it happens

Trigger: Calling Image.Load or Image.Identify on an ICO/CUR whose ICONDIRENTRY has Reserved != 0, BytesInRes == 0, ImageOffset < directory size, or ImageOffset >= stream length — e.g. corrupted directory entries or maliciously crafted offsets.

Common situations: Corrupted or hand-edited .ico files; files truncated after the directory so offsets exceed the stream; icon generators writing incorrect offsets; fuzzed/attacker-supplied icon inputs.

Related errors


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

Appendix: source

Thrown at src/ImageSharp/Formats/Icon/IconDecoderCore.cs:353

    /// <summary>
    /// Creates a seekable view bounded to one directory entry's declared payload.
    /// </summary>
    /// <param name="frameStream">The reusable bounded payload stream.</param>
    /// <param name="stream">The containing icon stream.</param>
    /// <param name="basePosition">The absolute start of the icon resource.</param>
    /// <param name="entry">The directory entry describing the payload.</param>
    private void SetFrameStreamBounds(IconFrameStream frameStream, BufferedReadStream stream, long basePosition, in IconDirEntry entry)
    {
        long available = stream.Length - basePosition;
        uint directorySize = (uint)(IconDir.Size + (this.fileHeader.Count * IconDirEntry.Size));

        // Offsets are relative to the icon resource and must not point into its directory or at or beyond its containing stream.
        if (entry.Reserved is not 0
            || entry.BytesInRes is 0
            || entry.ImageOffset < directorySize
            || entry.ImageOffset >= available)
        {
            throw new InvalidImageContentException("The icon directory contains an invalid image resource range.");
        }

        long remaining = available - entry.ImageOffset;
        long length = entry.BytesInRes;
        if (length > remaining)
        {
            if (this.fileHeader.Count is not 1)
            {
                // Clamping a multi-entry resource could expose the next image payload to the current child decoder.
                throw new InvalidImageContentException("The icon directory contains an invalid image resource range.");
            }

            // Some established single-image ICO files overstate BytesInRes but contain a complete payload.
            // The containing stream is still a safe hard boundary because no sibling image can follow it.
            length = remaining;
        }

        frameStream.Reset(basePosition + entry.ImageOffset, length);

View on GitHub (pinned to 59ce6af6fc)