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

  1. Verify each embedded entry decodes standalone (extract the payload at ImageOffset with BytesInRes length and load it as PNG/BMP)
  2. Re-export the icon with a known-good tool (e.g. icoconvert, ImageMagick) or from original assets
  3. Catch InvalidImageContentException and fall back to a placeholder icon
  4. 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

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


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)