SixLabors/ImageSharp · error · InvalidImageContentException
The ANI file contains a truncated RIFF list.
Error message
The ANI file contains a truncated RIFF list.
What it means
Thrown by AniDecoderCore.ReadList when the remaining bytes between the current stream position and the declared list end are fewer than 4 bytes, so the RIFF list type field cannot be read. The library treats this as corrupt content rather than guessing. It indicates the ANI file declares a RIFF list whose payload is shorter than its declared structure.
Solutions
- Re-obtain the ANI file from a trusted source and verify it is complete (compare file size/checksum).
- Validate the RIFF chunk sizes with a hex editor or riff inspection tool before decoding.
- Catch InvalidImageContentException and reject the file as corrupt instead of attempting decode.
Example fix
// before
var image = Image.Load("broken.ani");
// after
try { var image = Image.Load("broken.ani"); }
catch (InvalidImageContentException ex) { Console.WriteLine($"Corrupt ANI: {ex.Message}"); } Defensive patterns
Strategy: try-catch
Validate before calling
static bool IsPlausibleAni(byte[] bytes) => bytes.Length >= 12 && bytes.AsSpan(0, 4).SequenceEqual("RIFF"u8) && bytes.AsSpan(8, 4).SequenceEqual("ACON"u8) && bytes.Length >= BitConverter.ToUInt32(bytes, 4) + 8; Try / catch
try { var image = Image.Load(path); } catch (InvalidImageContentException ex) { log.Warn($"Corrupt ANI rejected: {ex.Message}"); } Prevention
- Verify file completeness (size/checksum) before decoding untrusted ANI files
- Use Image.Identify as a cheap pre-check before full decode
- Validate RIFF chunk hierarchy with an inspector tool for hand-crafted files
When it happens
Trigger: Decoding an ANI file via Image.LoadAsync/Image.IdentifyAsync where a RIFF list (RIFF/ 'acon' or 'fram') payload ends fewer than 4 bytes after the list header, i.e. a truncated list type field.
Common situations: Partially downloaded ANI files, files truncated by transfer tools, hand-crafted or fuzzed ANI files with incorrect list sizes in the RIFF chunk headers.
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
- The stream does not contain an ANI RIFF container.
- The ANI RIFF container size is invalid.
- The ANI file does not contain an animation header.
- The ANI animation header is truncated.
- The ANI animation header declares an invalid size.
AI-assisted analysis of SixLabors/ImageSharp@59ce6af6fc (2026-09-13).
Data as JSON: /api/errors/4d0854ef4c527d90.
Report an issue: GitHub.
Appendix: source
Thrown at src/ImageSharp/Formats/Ani/AniDecoderCore.cs:335
this.aniMetadata.Width = this.header.Width;
this.aniMetadata.Height = this.header.Height;
this.aniMetadata.BitCount = this.header.BitCount;
this.aniMetadata.Planes = this.header.Planes;
this.aniMetadata.DisplayRate = this.header.DisplayRate;
this.aniMetadata.Flags = this.header.Flags;
}
/// <summary>
/// Reads a RIFF list type and records or parses its contents.
/// </summary>
/// <param name="stream">The ANI stream.</param>
/// <param name="listEnd">The exclusive end of the list payload.</param>
private void ReadList(BufferedReadStream stream, long listEnd)
{
if (listEnd - stream.Position < sizeof(uint))
{
throw new InvalidImageContentException("The ANI file contains a truncated RIFF list.");
}
Span<byte> typeData = this.buffer[..sizeof(uint)];
ReadExactly(stream, typeData, "RIFF list type");
AniListType type = (AniListType)BinaryPrimitives.ReadUInt32LittleEndian(typeData);
switch (type)
{
case AniListType.Frames:
// Defer nested decoding until the complete container has supplied any later seq/rate chunks.
this.frameLists.Add((stream.Position, listEnd));
break;
case AniListType.Info when !this.Options.SkipMetadata:
this.ExecuteAncillarySegmentAction(() => this.ReadInfoList(stream, listEnd));
break;
}
}
View on GitHub (pinned to 59ce6af6fc)