SixLabors/ImageSharp · error · ImageFormatException
ANI resolution variants must use the same embedded format.
Error message
ANI resolution variants must use the same embedded format.
What it means
All frames in one resolution-variant group (same positive SequenceNumber) become variants of a single embedded resource, which must have one child format. If a later frame in the group declares a different AniFrameMetadata.FrameFormat than the group's first frame, the encoder throws ImageFormatException.
Solutions
- Set the same FrameFormat on every frame that shares a SequenceNumber.
- Give each differently-formatted frame its own SequenceNumber so it is treated as an independent step.
- Normalize metadata right before encoding with a loop over image.Frames.
Example fix
// before f0.Metadata.GetAniMetadata().FrameFormat = AniFrameFormat.Ico; f1.Metadata.GetAniMetadata().FrameFormat = AniFrameFormat.Cur; // same group // after f0.Metadata.GetAniMetadata().FrameFormat = AniFrameFormat.Ico; f1.Metadata.GetAniMetadata().FrameFormat = AniFrameFormat.Ico;
Defensive patterns
Strategy: validation
Validate before calling
var groups = image.Frames.Select((f,i) => (f.Metadata.GetAniMetadata(), i))
.GroupBy(x => x.Item1.SequenceNumber).Where(g => g.Key > 0);
foreach (var g in groups)
if (g.Select(x => x.Item1.FrameFormat).Distinct().Count() > 1)
throw new InvalidOperationException("Variant group formats differ."); Try / catch
try { image.SaveAsAni(stream); }
catch (ImageFormatException ex) { Log(ex.Message); } Prevention
- Normalize FrameFormat per SequenceNumber group before encoding.
- Assign distinct SequenceNumbers to frames with different formats.
- Re-verify metadata after merging frames from multiple sources.
When it happens
Trigger: Encoding an ANI where frames sharing a SequenceNumber have differing FrameFormat values (e.g. first frame Ico, subsequent frame Cur or Bmp).
Common situations: Merging frames from different decoded cursors/icons into one variant group; copy-paste metadata edits changing only some frames' format.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- ANI contains an unsupported embedded frame format.
- ANI cannot mix bitmap resources with ICO or CUR resources.
- ANI bitmap resources cannot contain resolution variants.
- ANI resolution variants must use the same frame delay.
- ANI bitmap resources require a supported bit depth.
AI-assisted analysis of SixLabors/ImageSharp@59ce6af6fc (2026-09-13).
Data as JSON: /api/errors/76778151d88be36e.
Report an issue: GitHub.
Appendix: source
Thrown at src/ImageSharp/Formats/Ani/AniEncoderCore.cs:113
if (bitmapResources != (metadata.FrameFormat is AniFrameFormat.Bmp))
{
// AF_ICON applies to the complete file, so raw DIB resources cannot coexist with ICO/CUR resources.
throw new ImageFormatException("ANI cannot mix bitmap resources with ICO or CUR resources.");
}
if (bitmapResources && groupSize > 1)
{
// Only ICO/CUR directories can contain multiple resolution variants in one physical resource.
throw new ImageFormatException("ANI bitmap resources cannot contain resolution variants.");
}
// All variants share one animation step, which requires one child format and one rate value.
for (int i = 1; i < groupSize; i++)
{
AniFrameMetadata current = image.Frames[frameIndex + i].Metadata.GetAniMetadata();
if (current.FrameFormat != metadata.FrameFormat)
{
throw new ImageFormatException("ANI resolution variants must use the same embedded format.");
}
if (current.FrameDelay != metadata.FrameDelay)
{
throw new ImageFormatException("ANI resolution variants must use the same frame delay.");
}
}
uint frameDelay = metadata.FrameDelay is 0 ? displayRate : metadata.FrameDelay;
hasVariableRates |= frameDelay != displayRate;
maxGroupSize = Math.Max(maxGroupSize, groupSize);
groupCount++;
frameIndex += groupSize;
}
// Icon-based ANI files leave global geometry and pixel layout at zero because each ICO/CUR entry owns those values.
AniHeader header = new()
{View on GitHub (pinned to 59ce6af6fc)