Intervention/image · error · DecoderException

Input is not valid Base64-encoded data

Error message

Input is not valid Base64-encoded data

What it means

base64_decode() in strict mode returned false: the input contains characters outside the standard Base64 alphabet, so it cannot be decoded at all. This is the character-level check; the separate round-trip check (error 89) catches structurally invalid but decodable input.

Source

Thrown at src/Drivers/AbstractDecoder.php:89

    /**
     * Decodes given base64 encoded data.
     *
     * @throws InvalidArgumentException
     * @throws DecoderException
     */
    protected function decodeBase64Data(mixed $input): string
    {
        if (!is_string($input) && !$input instanceof Stringable) {
            throw new InvalidArgumentException(
                'Base64-encoded data must be either of type string or instance of Stringable',
            );
        }

        $decoded = base64_decode((string) $input, true);

        if ($decoded === false) {
            throw new DecoderException('Input is not valid Base64-encoded data');
        }

        if (base64_encode($decoded) !== str_replace(["\n", "\r"], '', (string) $input)) {
            throw new DecoderException('Input is not valid Base64-encoded data');
        }

        return $decoded;
    }
}

View on GitHub (pinned to 5598b9e397)

Solutions

  1. Strip any 'data:...;base64,' prefix so only the raw base64 payload remains
  2. Convert base64url to standard base64: str_replace(['-','_'], ['+','/'], $v) and re-pad with '='
  3. Regenerate the payload with standard base64 (e.g. PHP base64_encode or JS btoa) on the producing side

Example fix

// before
$image = $manager->read($base64urlString);

// after
$std = str_replace(['-', '_'], ['+', '/'], $base64urlString);
$std .= str_repeat('=', (4 - strlen($std) % 4) % 4);
$image = $manager->read($std);
Defensive patterns

Strategy: validation

Validate before calling

$payload = preg_replace('#^data:[^,]+,#', '', $input); // strip data-uri prefix
$payload = str_replace(['-', '_'], ['+', '/'], $payload); // base64url -> base64
if (base64_decode($payload, true) === false) {
    throw new \RuntimeException('Not valid base64');
}

Type guard

function looksLikeBase64(string $value): bool
{
    return preg_match('/^[A-Za-z0-9+\/=\r\n]+$/', $value) === 1;
}

Try / catch

try {
    $image = $manager->read($payload);
} catch (DecoderException $e) {
    // invalid base64 - reject or re-request the source file
}

Prevention

When it happens

Trigger: Base64 payloads using the URL-safe alphabet ('-' and '_' instead of '+' and '/'), a leftover 'data:image/png;base64,' prefix inside the payload, or binary garbage passed as base64.

Common situations: Frontends or microservices encoding with base64url (JWT-style encoders); concatenating the data-URI prefix with an already-prefixed string; mojibake from unescaped transport.

Related errors


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