SixLabors/ImageSharp · warning · InvalidImageContentException
The ANI sequence references a missing frame resource.
Error message
The ANI sequence references a missing frame resource.
What it means
During ANI decoding, each animation step is mapped to a frame resource either via the 'anih'-companion sequence ('seq ') chunk or, when absent, by positional index. This error is raised when a step's resource index is out of range or points to a slot that failed to decode. Because the sequence chunk is treated as ancillary (recoverable) metadata, the error is reported without aborting the whole decode, and any remaining valid steps are still decoded.
Solutions
- Regenerate or fix the ANI file so every 'seq ' entry is a valid index into the existing icon/frame resources (0-based, < resource count).
- Verify all embedded icon frames in the 'fram'/'icon' chunks decode correctly; re-encode frames with a known-good tool.
- If you only need the decodable frames, treat this as a warning: the decode succeeds with the remaining steps, but the animation will skip steps.
Example fix
// before: seq chunk referencing 5 resources
uint[] sequence = { 0, 1, 2, 3, 7 }; // 7 out of range
// after: indices clamped to valid resources
uint[] sequence = { 0, 1, 2, 3, 4 }; Defensive patterns
Strategy: try-catch
Try / catch
try
{
using Image<Rgba32> img = Image.Load<Rgba32>(aniPath);
}
catch (InvalidImageContentException ex)
{
// Recoverable: decode continues for valid steps; log and accept partial animation.
logger.LogWarning(ex, "ANI sequence references missing frames; partial decode accepted.");
} Prevention
- Regenerate the 'seq ' chunk whenever frames are added or removed from an ANI.
- Validate seq indices (0-based, < frame count) when building ANI files programmatically.
- Prefer authoring tools that emit sequence metadata automatically.
When it happens
Trigger: Calling Image.DecodeAsync (ANI decoder) on a file whose 'seq ' chunk contains an index >= the number of parsed frame resources, or whose positional step count exceeds decodable resources (e.g. an 'icon'/'fram' chunk failed to parse, leaving a null resource slot).
Common situations: Hand-edited or tool-corrupted ANI/cursor files where the seq chunk was not regenerated after icons were removed; ANI files whose embedded icon chunks are malformed and silently dropped by the parser, shifting index alignment.
Related errors
- The ANI file does not contain any decodable animation steps.
- The ANI RIFF container size is invalid.
- The ANI file does not contain any identifiable animation…
- The stream does not contain an ANI RIFF container.
- The ANI file does not contain an animation header.
AI-assisted analysis of SixLabors/ImageSharp@59ce6af6fc (2026-09-13).
Data as JSON: /api/errors/44e670b675c7b3c2.
Report an issue: GitHub.
Appendix: source
Thrown at src/ImageSharp/Formats/Ani/AniDecoderCore.cs:96
// Keep the owners alive and resolve their spans once; sequence and rate lookup occurs for every animation step.
IMemoryOwner<uint>? sequenceOwner = this.sequence;
bool hasSequence = sequenceOwner is not null;
ReadOnlySpan<uint> sequence = sequenceOwner is null ? [] : sequenceOwner.GetSpan();
ReadOnlySpan<uint> rates = this.rates is null ? [] : this.rates.GetSpan();
int stepCount = hasSequence ? sequence.Length : resources.Count;
int maxFrames = (int)this.Options.MaxFrames;
outputFrames.EnsureCapacity(Math.Min(maxFrames, resources.Count));
for (int step = 0; step < stepCount && outputFrames.Count < maxFrames; step++)
{
cancellationToken.ThrowIfCancellationRequested();
uint resourceIndex = hasSequence ? sequence[step] : (uint)step;
if (resourceIndex >= resources.Count || resources[(int)resourceIndex] is not { } resource)
{
// A bad ordering entry is recoverable ancillary data: the remaining valid steps can still be decoded.
this.ExecuteAncillarySegmentAction(() => throw new InvalidImageContentException("The ANI sequence references a missing frame resource."));
continue;
}
(AniFrameFormat format, Image<TPixel> resourceImage) = resource;
uint frameDelay = step < rates.Length ? rates[step] : this.aniMetadata.DisplayRate;
for (int i = 0; i < resourceImage.Frames.Count && outputFrames.Count < maxFrames; i++)
{
ImageFrame<TPixel> source = resourceImage.Frames[i];
ImageFrame<TPixel> target = new(this.Options.Configuration, this.Dimensions);
// ANI flattens differently sized ICO/CUR variants into one ImageSharp frame collection.
// The common canvas preserves that invariant, while encoding dimensions retain the source size.
for (int y = 0; y < source.Height; y++)
{
source.PixelBuffer.DangerousGetRowSpan(y).CopyTo(target.PixelBuffer.DangerousGetRowSpan(y));
}View on GitHub (pinned to 59ce6af6fc)