{"record":{"id":"bf06395a0b38cb16","repo":"SixLabors/ImageSharp","slug":"the-ani-file-contains-a-truncated-ico-or-cur-resource","errorCode":null,"errorMessage":"The ANI file contains a truncated ICO or CUR resource.","messagePattern":"The ANI file contains a truncated ICO or CUR resource\\.","errorType":"exception","errorClass":"InvalidImageContentException","httpStatus":null,"severity":"error","filePath":"src/ImageSharp/Formats/Ani/AniDecoderCore.cs","lineNumber":664,"sourceCode":"    }\n\n    /// <summary>\n    /// Determines the embedded resource format from the ANI header and ICO/CUR directory prefix.\n    /// </summary>\n    /// <param name=\"stream\">The bounded frame-resource stream.</param>\n    /// <returns>The embedded resource format.</returns>\n    private AniFrameFormat GetFrameFormat(Stream stream)\n    {\n        // Without AF_ICON, the icon chunk payload is a raw DIB and has no ICO/CUR directory prefix to inspect.\n        if (!this.header.Flags.HasFlag(AniHeaderFlags.IsIcon))\n        {\n            return AniFrameFormat.Bmp;\n        }\n\n        Span<byte> iconHeader = this.buffer[..AniConstants.IconDirHeaderSize];\n        if (stream.Read(iconHeader) != iconHeader.Length)\n        {\n            throw new InvalidImageContentException(\"The ANI file contains a truncated ICO or CUR resource.\");\n        }\n\n        IconFileType type = (IconFileType)BinaryPrimitives.ReadUInt16LittleEndian(iconHeader[2..]);\n        return type switch\n        {\n            IconFileType.ICO => AniFrameFormat.Ico,\n            IconFileType.CUR => AniFrameFormat.Cur,\n            _ => throw new InvalidImageContentException(\"The ANI file contains an unsupported icon resource.\")\n        };\n    }\n\n    /// <summary>\n    /// Decodes one embedded ANI frame resource.\n    /// </summary>\n    /// <typeparam name=\"TPixel\">The destination pixel type.</typeparam>\n    /// <param name=\"format\">The embedded resource format.</param>\n    /// <param name=\"options\">The nested decoder options.</param>\n    /// <param name=\"stream\">The bounded resource stream.</param>","sourceCodeStart":646,"sourceCodeEnd":682,"githubUrl":"https://github.com/SixLabors/ImageSharp/blob/59ce6af6fc29027cda277ef62d4d1694a8acce91/src/ImageSharp/Formats/Ani/AniDecoderCore.cs#L646-L682","documentation":"Thrown by AniDecoderCore when reading the embedded ICO/CUR frame's icon directory header: the stream returned fewer bytes than IconDirHeaderSize. The ANI declares an embedded icon resource but the bytes end prematurely. The library refuses to decode a partial resource.","triggerScenarios":"Decoding an ANI file whose 'icon' chunk payload ends before the 6-byte ICONDIR header can be read, e.g. truncated icon data inside the 'fram' list.","commonSituations":"ANI files truncated mid-download, corrupted cursor bundles, files edited or concatenated incorrectly, fuzzed inputs with oversized chunk size fields.","solutions":["Re-download or re-export the ANI file so the embedded icon payloads are complete.","Verify the 'icon' chunk sizes match the actual payload bytes with a RIFF inspector.","Catch InvalidImageContentException and treat the file as corrupt."],"exampleFix":"// before\nvar image = Image.Load(\"partial.ani\");\n// after\nif (!Image.TryLoad(\"partial.ani\", out var image)) { /* handle corrupt file */ }","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { var image = await Image.LoadAsync(stream); } catch (InvalidImageContentException ex) { return DecodeResult.CorruptFile; }","preventionTips":["Ensure ANI files are transferred in binary mode without truncation","Run Image.IdentifyAsync on untrusted files before decoding","Reject files whose 'icon' chunk sizes exceed remaining bytes"],"tags":["image-decoding","ani","ico","cur","truncated-file"],"backgroundTag":"invalid-argument-format","analyzedSha":"59ce6af6fc29027cda277ef62d4d1694a8acce91","analyzedAt":"2026-09-13T18:34:59.331Z","contentChangedAt":"2026-09-13T18:34:59.331Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}