SixLabors/ImageSharp · error · InvalidImageContentException

The ANI file contains a truncated ICO or CUR resource.

Error message

The ANI file contains a truncated ICO or CUR resource.

What it means

Thrown by AniDecoderCore when reading the embedded ICO/CUR frame's icon directory header: the stream returned fewer bytes than IconDirHeaderSize. The ANI declares an embedded icon resource but the bytes end prematurely. The library refuses to decode a partial resource.

Solutions

  1. Re-download or re-export the ANI file so the embedded icon payloads are complete.
  2. Verify the 'icon' chunk sizes match the actual payload bytes with a RIFF inspector.
  3. Catch InvalidImageContentException and treat the file as corrupt.

Example fix

// before
var image = Image.Load("partial.ani");
// after
if (!Image.TryLoad("partial.ani", out var image)) { /* handle corrupt file */ }
Defensive patterns

Strategy: try-catch

Try / catch

try { var image = await Image.LoadAsync(stream); } catch (InvalidImageContentException ex) { return DecodeResult.CorruptFile; }

Prevention

When it happens

Trigger: Decoding an ANI file whose 'icon' chunk payload ends before the 6-byte ICONDIR header can be read, e.g. truncated icon data inside the 'fram' list.

Common situations: ANI files truncated mid-download, corrupted cursor bundles, files edited or concatenated incorrectly, fuzzed inputs with oversized chunk size fields.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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

Appendix: source

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

    }

    /// <summary>
    /// Determines the embedded resource format from the ANI header and ICO/CUR directory prefix.
    /// </summary>
    /// <param name="stream">The bounded frame-resource stream.</param>
    /// <returns>The embedded resource format.</returns>
    private AniFrameFormat GetFrameFormat(Stream stream)
    {
        // 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>

View on GitHub (pinned to 59ce6af6fc)