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
- Verify each entry: ImageOffset must be >= 6 + 16*Count and ImageOffset + BytesInRes must fit within the file
- Re-export the icon with a reliable tool
- Catch InvalidImageContentException and reject/treat the file as corrupt
- 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
- Validate directory entry offsets and sizes against file length before loading
- Treat untrusted icons as hostile input; validate first
- Regenerate icons whose entries have Reserved != 0
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
- The icon file does not contain any decodable image entries.
- The icon file does not contain any identifiable image…
- The icon directory header is invalid.
- The embedded icon resource contains an invalid seek offset.
- Not enough bytes to read icon header.
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)