{"record":{"id":"ae78465eb51ec573","repo":"Intervention/image","slug":"failed-to-decode-gif-format","errorCode":null,"errorMessage":"Failed to decode GIF format","messagePattern":"Failed to decode GIF format","errorType":"exception","errorClass":"ImageDecoderException","httpStatus":null,"severity":"error","filePath":"src/Drivers/Gd/Decoders/NativeObjectDecoder.php","lineNumber":82,"sourceCode":"    /**\n     * Decode image from given GIF source which can be either a file path or binary data.\n     *\n     * Depending on the configuration, this is taken over by the native GD function\n     * or, if animations are required, by our own extended decoder.\n     *\n     * @throws InvalidArgumentException\n     * @throws ImageDecoderException\n     * @throws DriverException\n     * @throws StateException\n     */\n    protected function decodeGif(string $input): ImageInterface\n    {\n        // create non-animated image depending on config\n        if ($this->driver()->config()->decodeAnimation === false) {\n            $native = $this->isGifFormat($input) ? @imagecreatefromstring($input) : @imagecreatefromgif($input);\n\n            if ($native === false) {\n                throw new ImageDecoderException('Failed to decode GIF format');\n            }\n\n            $image = self::decode($native);\n            $image->origin()->setMediaType('image/gif');\n\n            return $image;\n        }\n\n        try {\n            // create empty core\n            $core = new Core();\n\n            // add frames to core\n            $splitter = GifSplitter::decode($input)\n                ->split()\n                ->flatten()\n                ->each(function (GdImage $native, int $delay) use ($core): void {\n                    $core->push(new Frame($native, $delay / 100));","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/Intervention/image/blob/5598b9e39751c34afc5cdee84abef77f92c26f68/src/Drivers/Gd/Decoders/NativeObjectDecoder.php#L64-L100","documentation":"Thrown by the GD driver when a GIF is decoded with animation decoding disabled (config option decodeAnimation=false). In that mode the decoder calls imagecreatefromgif()/imagecreatefromstring() and both return false, so the raw bytes could not be parsed as a GIF at all. The input is typically truncated, corrupt, or not actually GIF data.","triggerScenarios":"ImageManager with the GD driver and option ['decodeAnimation' => false], then ->read($gifData) where $gifData is a truncated upload, a renamed non-GIF file (e.g. an HTML error page saved as .gif), or a GIF on a GD build without GIF read support.","commonSituations":"User uploads cut off mid-transfer (upload_max_filesize or client abort), fetching remote images without checking the HTTP status so an error body is decoded, files corrupted by ASCII-mode FTP transfers, unusual shared-hosting GD builds.","solutions":["Verify the input really is a GIF before decoding: (new finfo())->buffer($data) or getimagesize()","If corrupt, re-download or reject the source instead of retrying the same bytes","Check gd_info() in the failing environment includes GIF support","Switch the manager to the Imagick driver (ImageManager::usingDriver(ImagickDriver::class)) which tolerates more GIF variants","Wrap reads in try/catch on ImageDecoderException and quarantine bad files"],"exampleFix":"// before\n$image = $manager->read($uploadPath); // throws on corrupt GIF\n\n// after\n$mime = (new finfo())->file($uploadPath);\nif (!str_starts_with($mime, 'image/')) {\n    throw new RuntimeException('Unsupported or corrupt image: ' . $mime);\n}\n$image = $manager->read($uploadPath);","handlingStrategy":"try-catch","validationCode":"$data = file_get_contents($path);\nif (!str_starts_with((new finfo())->buffer($data), 'image/gif')) {\n    throw new InvalidArgumentException('Source is not a GIF');\n}\n$manager->read($data);","typeGuard":null,"tryCatchPattern":"try {\n    $image = $manager->read($gifData);\n} catch (ImageDecoderException $e) {\n    // reject upload, log, or re-fetch the source\n}","preventionTips":["Validate uploads with finfo/getimagesize before processing","Check HTTP status when downloading remote images","Do not retry decode on identical corrupt bytes"],"tags":["gif","gd","image-decoding","upload-validation"],"backgroundTag":"image-decode-failed","analyzedSha":"5598b9e39751c34afc5cdee84abef77f92c26f68","analyzedAt":"2026-08-23T02:17:31.068Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}