SixLabors/ImageSharp · error · InvalidImageContentException

The ANI file contains an unsupported icon resource.

Error message

The ANI file contains an unsupported icon resource.

What it means

Thrown by AniDecoderCore when the 16-bit resource type field in an embedded icon directory header is neither ICO (1) nor CUR (2). The library only supports those two embedded resource types inside ANI files. Any other type value is treated as invalid content.

Solutions

  1. Rebuild the ANI with a compliant tool so embedded resources are ICO or CUR type.
  2. Inspect the icon directory bytes at the chunk offset and fix the wType field to 1 or 2.
  3. Catch InvalidImageContentException and reject the file.
Defensive patterns

Strategy: try-catch

Validate before calling

// Peek icon dir type: bytes at icon chunk payload offset +2, little-endian ushort; must be 1 (ICO) or 2 (CUR)
ushort type = BitConverter.ToUInt16(iconPayload, 2);
bool ok = type is 1 or 2;

Try / catch

try { var image = Image.Load(path); } catch (InvalidImageContentException ex) when (ex.Message.Contains("unsupported icon resource")) { /* rebuild file */ }

Prevention

When it happens

Trigger: Decoding an ANI file where an 'icon' chunk's ICONDIR wType field holds a value other than 1 (ICO) or 2 (CUR), such as 0 or 3+.

Common situations: Corrupted or hand-edited ANI files, files produced by non-conformant tools that write wrong resource types, fuzzed inputs.

Related errors


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

Appendix: source

Thrown at src/ImageSharp/Formats/Ani/AniDecoderCore.cs:672

    {
        // Without AF_ICON, the icon chunk payload is a raw DIB and has no ICO/CUR directory prefix to inspect.
        if (!this.header.Flags.HasFlag(AniHeaderFlags.IsIcon))
        {
            return AniFrameFormat.Bmp;
        }

        Span<byte> iconHeader = this.buffer[..AniConstants.IconDirHeaderSize];
        if (stream.Read(iconHeader) != iconHeader.Length)
        {
            throw new InvalidImageContentException("The ANI file contains a truncated ICO or CUR resource.");
        }

        IconFileType type = (IconFileType)BinaryPrimitives.ReadUInt16LittleEndian(iconHeader[2..]);
        return type switch
        {
            IconFileType.ICO => AniFrameFormat.Ico,
            IconFileType.CUR => AniFrameFormat.Cur,
            _ => throw new InvalidImageContentException("The ANI file contains an unsupported icon resource.")
        };
    }

    /// <summary>
    /// Decodes one embedded ANI frame resource.
    /// </summary>
    /// <typeparam name="TPixel">The destination pixel type.</typeparam>
    /// <param name="format">The embedded resource format.</param>
    /// <param name="options">The nested decoder options.</param>
    /// <param name="stream">The bounded resource stream.</param>
    /// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
    /// <returns>The decoded resource.</returns>
    private static Image<TPixel> DecodeFrame<TPixel>(AniFrameFormat format, DecoderOptions options, Stream stream, CancellationToken cancellationToken)
        where TPixel : unmanaged, IPixel<TPixel>
        => format switch
        {
            AniFrameFormat.Ico => new IcoDecoderCore(options).Decode<TPixel>(options.Configuration, stream, cancellationToken),
            AniFrameFormat.Cur => new CurDecoderCore(options).Decode<TPixel>(options.Configuration, stream, cancellationToken),

View on GitHub (pinned to 59ce6af6fc)