SixLabors/ImageSharp · error · InvalidImageContentException
The icon file does not contain any decodable image entries.
Error message
The icon file does not contain any decodable image entries.
What it means
Thrown during icon decoding when the directory lists entries but none of the child images (PNG or BMP payloads) could actually be decoded, so no image data is available to build the result. SixLabors.ImageSharp throws InvalidImageContentException because the container is structurally present but contains no usable image payloads.
Solutions
- Verify each embedded entry decodes standalone (extract the payload at ImageOffset with BytesInRes length and load it as PNG/BMP)
- Re-export the icon with a known-good tool (e.g. icoconvert, ImageMagick) or from original assets
- Catch InvalidImageContentException and fall back to a placeholder icon
- Check the file is genuinely an ICO/CUR and not a renamed PNG/other format
Example fix
// before
var image = Image.Load("app.ico");
// after
try
{
var image = Image.Load("app.ico");
}
catch (InvalidImageContentException)
{
// no decodable child entries in the icon
image = null; // use fallback asset
} Defensive patterns
Strategy: try-catch
Validate before calling
// basic ICO sanity: ICONDIR present with at least one entry
static bool LooksLikeNonEmptyIco(string path)
{
var b = File.ReadAllBytes(path);
return b.Length >= 22 && b[0] == 0 && b[1] == 0 && b[2] is 1 or 2 && b[4] | (b[5] << 8) > 0;
} Type guard
static bool IsInvalidImageContent(Exception ex) => ex is InvalidImageContentException;
Try / catch
try
{
var image = Image.Load(icoPath);
}
catch (InvalidImageContentException)
{
// no decodable entries: use a fallback icon
image = LoadFallbackIcon();
} Prevention
- Obtain icons from trusted generators
- Pre-validate entry offsets/sizes before loading untrusted icons
- Always keep a fallback icon asset in the app
When it happens
Trigger: Calling Image.Load/Decode on an ICO/CUR whose directory entries all fail child decoding — e.g. every entry's payload is corrupt, zero-length after range validation, or uses an unsupported inner format.
Common situations: Malformed ICO files produced by buggy converters; icons whose embedded PNG/BMP payloads are damaged; files renamed to .ico that are not real icon resources; truncated icon payloads after BytesInRes clamping.
Related errors
- The icon file does not contain any identifiable image…
- The icon directory header is invalid.
- The icon directory contains an invalid image resource range.
- 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/511f9dcdc916f4ac.
Report an issue: GitHub.
Appendix: source
Thrown at src/ImageSharp/Formats/Icon/IconDecoderCore.cs:78
Span<byte> flag = this.buffer[..PngConstants.HeaderBytes.Length];
CheckEndOfStream(frameStream.Read(flag), flag.Length);
frameStream.Position = 0;
bool isPng = flag.SequenceEqual(PngConstants.HeaderBytes);
IconFrameCompression compression = isPng ? IconFrameCompression.Png : IconFrameCompression.Bmp;
// Frames remain alive until the largest decoded dimensions are known and the common canvas can be allocated.
Image<TPixel> decoded = this.GetDecoder(isPng).Decode<TPixel>(this.Options.Configuration, frameStream, cancellationToken);
decodedEntries[decodedCount++] = (entryIndex, decoded, compression);
// The embedded header is authoritative because a zero directory dimension can represent 256 pixels or a larger Vista-era PNG.
this.Dimensions = new Size(Math.Max(this.Dimensions.Width, decoded.Width), Math.Max(this.Dimensions.Height, decoded.Height));
});
}
if (decodedCount is 0)
{
throw new InvalidImageContentException("The icon file does not contain any decodable image entries.");
}
// General profiles belong to the icon result even though the first successfully decoded child image is temporary.
ImageMetadata metadata = decodedEntries[0].Image.Metadata.DeepClone();
BmpMetadata? bmpMetadata = null;
PngMetadata? pngMetadata = null;
ImageFrame<TPixel>[] frames = new ImageFrame<TPixel>[decodedCount];
int initializedFrameCount = 0;
try
{
for (int i = 0; i < decodedCount; i++)
{
BmpBitsPerPixel bitsPerPixel = BmpBitsPerPixel.Bit32;
ReadOnlyMemory<Color>? colorTable = null;
Image<TPixel> decoded = decodedEntries[i].Image;
ref IconDirEntry entry = ref this.entries[decodedEntries[i].EntryIndex];
ImageFrame<TPixel> source = decoded.Frames.RootFrameUnsafe;View on GitHub (pinned to 59ce6af6fc)