SixLabors/ImageSharp · error · InvalidImageContentException
The ANI animation header is truncated.
Error message
The ANI animation header is truncated.
What it means
The 'anih' chunk must be at least AniHeader.Size (36) bytes to hold the full ANI header structure. When the chunk declares a smaller size, the header cannot be parsed completely and InvalidImageContentException is thrown. This catches headers written by non-conformant producers or truncated files.
Solutions
- Check the 'anih' chunk size field: it must be >= 36; extend the header to 36 bytes (padding the tail) if you control the writer.
- Re-download the file if the chunk payload was truncated in transit.
- Re-export the animation with a mainstream tool that always emits the full 36-byte header.
Example fix
// before: [anih size=16][16 bytes] // after: [anih size=36][36 bytes incl. reserved fields]
Defensive patterns
Strategy: validation
Validate before calling
// Read the anih chunk size field and require >= 36 before decoding
static bool AnihChunkIsFullSize(string path)
{
using var fs = File.OpenRead(path);
Span<byte> buf = stackalloc byte[8];
fs.Seek(12, SeekOrigin.Begin);
while (fs.Read(buf) == 8)
{
uint sz = BinaryPrimitives.ReadUInt32LittleEndian(buf.Slice(4, 4));
if (buf.Slice(0, 4).SequenceEqual("anih"u8)) return sz >= 36 && fs.Length - fs.Position >= sz;
fs.Seek((long)((sz + 1) & ~1u), SeekOrigin.Current);
}
return false;
} Try / catch
try
{
using Image<Rgba32> img = Image.Load<Rgba32>(aniStream);
}
catch (InvalidImageContentException ex)
{
logger.LogError(ex, "ANI header chunk truncated.");
} Prevention
- Verify downloads are complete before parsing (truncation is the most common cause).
- Ensure ANI writers always emit the full 36-byte header, padding if needed.
- Check chunk size against remaining file length during ingestion.
When it happens
Trigger: Calling Decode/Identify where the 'anih' chunk's size field is < 36 — e.g. a 12- or 16-byte header from a buggy writer, or a chunk whose declared size exceeds remaining stream bytes so only part is readable.
Common situations: Truncated downloads where the 'anih' chunk size was written correctly but the payload was cut off; minimal header variants from old or hand-rolled ANI writers.
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 declares an invalid size.
- The ANI file contains a truncated RIFF list.
AI-assisted analysis of SixLabors/ImageSharp@59ce6af6fc (2026-09-13).
Data as JSON: /api/errors/9bd0aab3b715123b.
Report an issue: GitHub.
Appendix: source
Thrown at src/ImageSharp/Formats/Ani/AniDecoderCore.cs:306
stream.Position = GetPaddedEnd(dataEnd, chunk.Size, containerEnd);
}
if (!headerFound)
{
throw new InvalidImageContentException("The ANI file does not contain an animation header.");
}
}
/// <summary>
/// Parses the mandatory 36-byte ANI header and copies its observable values to image metadata.
/// </summary>
/// <param name="stream">The ANI stream.</param>
/// <param name="chunkSize">The ANI header chunk size.</param>
private void ReadAniHeader(BufferedReadStream stream, uint chunkSize)
{
if (chunkSize < AniHeader.Size)
{
throw new InvalidImageContentException("The ANI animation header is truncated.");
}
Span<byte> data = this.buffer;
ReadExactly(stream, data, "ANI header");
this.header = AniHeader.Parse(data);
if (this.header.BytesInHeader < AniHeader.Size || this.header.BytesInHeader > chunkSize)
{
throw new InvalidImageContentException("The ANI animation header declares an invalid size.");
}
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;
}View on GitHub (pinned to 59ce6af6fc)