Intervention/image · error · ImageDecoderException
Unable to Base64-decode image from string
Error message
Unable to Base64-decode image from string
What it means
Thrown by Base64ImageDecoder::decode when decodeBase64Data fails: base64_decode($input, true) returned false, or the decode/re-encode round trip did not match the input. In other words, the string routed to the base64 decoder is not canonical, strictly-valid Base64, so it is rejected with an ImageDecoderException before image decoding begins.
Source
Thrown at src/Drivers/Gd/Decoders/Base64ImageDecoder.php:37
*
* @see DecoderInterface::supports()
*/
public function supports(mixed $input): bool
{
return $this->couldBeBase64Data($input);
}
/**
* {@inheritdoc}
*
* @see DecoderInterface::decode()
*/
public function decode(mixed $input): ImageInterface
{
try {
$data = $this->decodeBase64Data($input);
} catch (DecoderException) {
throw new ImageDecoderException('Unable to Base64-decode image from string');
}
try {
return parent::decode($data);
} catch (DecoderException) {
throw new ImageDecoderException('Base64-encoded data contains unsupported image type');
}
}
}
View on GitHub (pinned to 5598b9e397)
Solutions
- Sanitize the string: strip any 'data:...;base64,' prefix, remove whitespace/newlines, and re-pad with '=' to a multiple of 4
- If the value is a full data URI, pass it as-is so DataUriImageDecoder handles it, or parse it with DataUri::parse() first
- Validate before reading: base64_decode($s, true) !== false && base64_encode(base64_decode($s, true)) === preg_replace('/\s+/', '', $s)
- For base64url input, translate '-' => '+', '_' => '/' before handing it over
Example fix
// before
$image = $manager->read($uploadedBase64); // contains "data:image/png;base64," prefix
// ImageDecoderException: Unable to Base64-decode image from string
// after
$b64 = preg_replace('#^data:[^;]+;base64,#', '', $uploadedBase64);
$b64 = str_replace(["\n", "\r", ' '], '', $b64);
$image = $manager->read($b64); Defensive patterns
Strategy: validation
Validate before calling
function normalizeBase64(string $input): string
{
$b64 = preg_replace('#^data:[^;]+;base64,#', '', $input);
$b64 = str_replace(["\n", "\r", ' '], '', $b64);
return $b64 . str_repeat('=', (4 - strlen($b64) % 4) % 4);
}
$b64 = normalizeBase64($input);
$decoded = base64_decode($b64, true);
if ($decoded === false || base64_encode($decoded) !== $b64) {
throw new RuntimeException('Not valid canonical Base64');
} Try / catch
try {
$image = $manager->read($b64);
} catch (\Intervention\Image\Exceptions\ImageDecoderException $e) {
if (str_contains($e->getMessage(), 'Base64-decode')) {
// fix the encoding of the source value; retrying the same string will not help
}
} Prevention
- Strip data-URI prefixes and all whitespace before passing base64 to read()
- Translate base64url alphabets ('-'/'_') to standard Base64 on the server edge
- Validate with base64_decode(strict) plus a re-encode round trip before storing
When it happens
Trigger: Passing a string ending in '=' that is not well-formed Base64 (that suffix alone makes supports() claim it); strings containing a 'data:image/...;base64,' prefix, whitespace, or URL-safe '-'/'_' alphabet; base64 with stripped padding that fails the base64_encode round-trip check; binary data misrouted into Base64ImageDecoder::decode directly.
Common situations: Frontend sends a data URI where the backend expected bare base64; JSON payloads where newlines were inserted into long base64 strings; copy-paste artifacts (truncated strings, ellipsis); client libraries using base64url (JWT-style) encoding for image payloads.
Related errors
- Base64-encoded data contains unsupported image type
- Data Uri contains unsupported image type
- Base64-encoded data must be either of type string or instanc
- Unsupported media type (MIME) ${mime}.
- Failed to read media (MIME) type from binary data
AI-assisted analysis of Intervention/image@5598b9e397 (2026-08-23).
Data as JSON: /api/errors/1aac573ee0ec2266.
Report an issue: GitHub.