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

  1. Set the same FrameFormat on every frame that shares a SequenceNumber.
  2. Give each differently-formatted frame its own SequenceNumber so it is treated as an independent step.
  3. 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

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


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)