SixLabors/ImageSharp · error · InvalidImageContentException

APNG Image must contain a acTL chunk and it must be located…

Error message

APNG Image must contain a acTL chunk and it must be located before any IDAT and fdAT chunks.

What it means

Thrown when an APNG's acTL (animation control) chunk is missing, or positioned illegally. The APNG specification requires acTL to appear before both the IDAT chunk (default image) and any fdAT (frame data) chunks, so the decoder can learn frame count and loop count before reading frames.

Solutions

  1. Re-encode the animation with a spec-compliant APNG encoder that writes acTL before IDAT/fdAT.
  2. If you manipulate chunks manually, move acTL so it precedes both IDAT and all fdAT chunks.
  3. Verify the chunk order with pngcheck or an APNG-aware validator.
  4. Catch InvalidImageContentException and reject the file.

Example fix

// before (wrong order)
WriteChunk(idat); WriteChunk(actl); WriteChunk(fdat...);
// after
WriteChunk(actl); WriteChunk(idat); WriteChunk(fdat...);
Defensive patterns

Strategy: validation

Try / catch

try
{
    using var image = Image.Load(stream);
}
catch (InvalidImageContentException ex) when (ex.Message.Contains("acTL"))
{
    // acTL missing or out of order — reject the animation
}

Prevention

When it happens

Trigger: Decoding an APNG whose acTL was stripped, or a file where acTL appears after IDAT/fdAT chunks — either hand-assembled or produced by a non-conformant encoder.

Common situations: Files spliced together by custom chunk-editing scripts, APNGs round-tripped through tools that drop or reorder unknown chunks, hand-written encoders writing chunks in the wrong order.

Related errors


AI-assisted analysis of SixLabors/ImageSharp@59ce6af6fc (2026-09-13). Data as JSON: /api/errors/6e0d5e3fa5dbede2. Report an issue: GitHub.

Appendix: source

Thrown at src/ImageSharp/Formats/Png/PngThrowHelper.cs:24

namespace SixLabors.ImageSharp.Formats.Png;

internal static class PngThrowHelper
{
    [DoesNotReturn]
    public static void ThrowInvalidImageContentException(string errorMessage) => throw new InvalidImageContentException(errorMessage);

    [DoesNotReturn]
    public static void ThrowInvalidHeader() => throw new InvalidImageContentException("PNG Image must contain a header chunk and it must be located before any other chunks.");

    [DoesNotReturn]
    public static void ThrowNoData() => throw new InvalidImageContentException("PNG Image does not contain a data chunk.");

    [DoesNotReturn]
    public static void ThrowMissingDefaultData() => throw new InvalidImageContentException("APNG Image does not contain a default data chunk.");

    [DoesNotReturn]
    public static void ThrowInvalidAnimationControl() => throw new InvalidImageContentException("APNG Image must contain a acTL chunk and it must be located before any IDAT and fdAT chunks.");

    [DoesNotReturn]
    public static void ThrowMissingFrameControl() => throw new InvalidImageContentException("One of APNG Image's frames do not have a frame control chunk.");

    [DoesNotReturn]
    public static void ThrowMissingPalette() => throw new InvalidImageContentException("PNG Image does not contain a palette chunk.");

    [DoesNotReturn]
    public static void ThrowInvalidChunkType() => throw new InvalidImageContentException("Invalid PNG data.");

    [DoesNotReturn]
    public static void ThrowInvalidChunkType(string message) => throw new InvalidImageContentException(message);

    [DoesNotReturn]
    public static void ThrowInvalidChunkCrc(string chunkTypeName) => throw new InvalidImageContentException($"CRC Error. PNG {chunkTypeName} chunk is corrupt!");

    [DoesNotReturn]
    public static void ThrowInvalidParameter(object value, string message, [CallerArgumentExpression(nameof(value))] string name = "")

View on GitHub (pinned to 59ce6af6fc)