Intervention/image · error · Intervention\Image\Exceptions\InvalidArgumentException

Image source must be binary data of type string or instance

Error message

Image source must be binary data of type string or instance of 

What it means

Thrown by BinaryImageDecoder::decode() when the input is neither a PHP string nor a Stringable object. The binary decoder only accepts raw binary image data as string(-like) input; resources, objects, arrays, or null are rejected before any decoding starts.

Source

Thrown at src/Drivers/Imagick/Decoders/BinaryImageDecoder.php:45

    public function supports(mixed $input): bool
    {
        return $this->couldBeBinaryData($input);
    }

    /**
     * {@inheritdoc}
     *
     * @see DecoderInterface::decode()
     *
     * @throws InvalidArgumentException
     * @throws ImageDecoderException
     * @throws DriverException
     * @throws StateException
     */
    public function decode(mixed $input): ImageInterface
    {
        if (!is_string($input) && !$input instanceof Stringable) {
            throw new InvalidArgumentException(
                'Image source must be binary data of type string or instance of ' . Stringable::class,
            );
        }

        $input = (string) $input;

        if ($input === '') {
            throw new InvalidArgumentException('Unable to decode binary data from empty string');
        }

        try {
            $imagick = new Imagick();
            $imagick->readImageBlob($input);
        } catch (ImagickException) {
            throw new ImageDecoderException('Failed to decode unsupported image format from binary data');
        }

        // decode image

View on GitHub (pinned to 5598b9e397)

Solutions

  1. Convert resources to strings first: stream_get_contents($resource) or (string) $response->getBody()
  2. For files prefer $manager->read($path) with the filepath decoder, or read the bytes with file_get_contents
  3. Null-check optional inputs before calling read()

Example fix

// before: resource passed as image source
$image = $manager->read(fopen($path, 'r'));

// after: string of bytes
$image = $manager->read(file_get_contents($path));
// or let the filepath decoder work:
$image = $manager->read($path);
Defensive patterns

Strategy: type-guard

Validate before calling

if (!is_string($input) && !$input instanceof Stringable) {
    throw new InvalidArgumentException('image source must be a string of bytes');
}
$image = $manager->read($input);

Type guard

function isBinaryLike(mixed $value): bool
{
    return is_string($value) || $value instanceof Stringable;
}

Try / catch

use Intervention\Image\Exceptions\InvalidArgumentException;

try {
    $image = $manager->read($input);
} catch (InvalidArgumentException $e) {
    // fix the caller: cast resources/streams to string before passing
    throw $e;
}

Prevention

When it happens

Trigger: Directly or via routing, calling $manager->read($x) where $x is a file handle from fopen(), a GdImage/Imagick object, an array, null from a failed lookup, or a stream resource from an HTTP client — on the code path where the binary decoder ends up handling it (e.g. a custom decoder chain or calling the decoder directly).

Common situations: Passing fopen('img.png', 'r') instead of file_get_contents(); passing a Guzzle PSR-7 stream; passing null after an optional request field was absent; Stringable value objects elsewhere in the app making developers assume any object works.

Related errors


AI-assisted analysis of Intervention/image@5598b9e397 (2026-08-23). Data as JSON: /api/errors/67ca2d7bc6be9e4e. Report an issue: GitHub.