{"record":{"id":"b4d8a34a9e27e6e3","repo":"SixLabors/ImageSharp","slug":"unexpected-end-of-stream-while-reading-gif-xmp-data","errorCode":null,"errorMessage":"Unexpected end of stream while reading gif XMP data","messagePattern":"Unexpected end of stream while reading gif XMP data","errorType":"exception","errorClass":"InvalidImageContentException","httpStatus":null,"severity":"error","filePath":"src/ImageSharp/Formats/Gif/Sections/GifXmpApplicationExtension.cs","lineNumber":36,"sourceCode":"    public int ContentLength => (this.Data.Length > 0) ? this.Data.Length + 269 : 0;\n\n    /// <summary>\n    /// Gets the raw Data.\n    /// </summary>\n    public byte[] Data { get; }\n\n    /// <summary>\n    /// Reads the XMP metadata from the specified stream.\n    /// </summary>\n    /// <param name=\"stream\">The stream to read from.</param>\n    /// <param name=\"allocator\">The memory allocator.</param>\n    /// <returns>The XMP metadata</returns>\n    public static GifXmpApplicationExtension Read(BufferedReadStream stream, MemoryAllocator allocator)\n    {\n        byte[] xmpBytes = ReadXmpData(stream, allocator, out bool terminated);\n        if (!terminated)\n        {\n            throw new InvalidImageContentException(\"Unexpected end of stream while reading gif XMP data\");\n        }\n\n        // Exclude the \"magic trailer\", see XMP Specification Part 3, 1.1.2 GIF\n        int xmpLength = xmpBytes.Length - 256; // 257 - unread 0x0\n        byte[] buffer = [];\n        if (xmpLength > 0)\n        {\n            buffer = new byte[xmpLength];\n            xmpBytes.AsSpan(0, xmpLength).CopyTo(buffer);\n            stream.Skip(1); // Skip the terminator.\n        }\n\n        return new GifXmpApplicationExtension(buffer);\n    }\n\n    public int WriteTo(Span<byte> buffer)\n    {\n        int bytesWritten = 0;","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/SixLabors/ImageSharp/blob/59ce6af6fc29027cda277ef62d4d1694a8acce91/src/ImageSharp/Formats/Gif/Sections/GifXmpApplicationExtension.cs#L18-L54","documentation":"Thrown when a GIF XMP application extension block is truncated: ReadXmpData reaches the end of the stream before finding the XMP magic trailer that terminates the payload. SixLabors.ImageSharp throws InvalidImageContentException because the image data itself is malformed/incomplete.","triggerScenarios":"Calling Image.Load/LoadAsync (or GifDecoder) on a GIF whose XMP application extension data chunk is cut off mid-extension, e.g. a partially downloaded or truncated file where the 0x00 magic trailer never appears.","commonSituations":"Interrupted downloads or uploads of GIFs; file corruption on disk; a tool or hand-rolled encoder writing an incomplete XMP sub-block; CDN/proxy truncation of large GIF payloads.","solutions":["Verify the GIF file is complete and re-download or re-export it from the original source","Wrap Image.Load in a try-catch for InvalidImageContentException and treat the file as corrupt","Check the GIF with a validator or hex inspector: the XMP block must end with the 257-byte magic trailer (0xFE followed by 256 bytes including the terminating 0x00)","If files come from a producer of GIFs, fix that encoder to emit the complete XMP block including the magic trailer"],"exampleFix":"// before\nvar image = Image.Load(\"animated.gif\");\n// after\ntry\n{\n    var image = Image.Load(\"animated.gif\");\n}\ncatch (InvalidImageContentException)\n{\n    // corrupt/truncated GIF (e.g. missing XMP magic trailer)\n    image = null;\n}","handlingStrategy":"try-catch","validationCode":"// GIF must contain a full XMP block ending in the magic trailer\nstatic bool GifLooksTruncated(string path) =>\n    new FileInfo(path).Length == 0; // real content validation happens on load","typeGuard":"static bool IsValidImageContentException(Exception ex) => ex is InvalidImageContentException;","tryCatchPattern":"try\n{\n    var image = Image.Load(path);\n}\ncatch (InvalidImageContentException ex)\n{\n    // GIF XMP data truncated: file is corrupt, do not retry\n    HandleCorruptImage(path, ex);\n}","preventionTips":["Validate downloads with checksums before loading GIFs","Reject zero-length or obviously truncated files early","Fix producers to write the complete XMP magic trailer"],"tags":["gif","invalid-image-content","xmp","truncated-file"],"backgroundTag":"invalid-image-content","analyzedSha":"59ce6af6fc29027cda277ef62d4d1694a8acce91","analyzedAt":"2026-09-13T18:34:59.331Z","contentChangedAt":"2026-09-13T18:34:59.331Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}