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

Failed to apply {class}, unable to set ICC color profile

Error message

Failed to apply {class}, unable to set ICC color profile

What it means

setProfile() passes the profile binary to Imagick::profileImage('icc', $binary); a false return triggers this ModifierException. Typical native causes: the payload is not a valid ICC profile (truncated download, wrong file), or the profile's color space does not match the image data, e.g. assigning a CMYK profile to RGB pixels. The false branch is the rarer path; invalid profiles more often throw ImagickException (covered by the sibling catch).

Source

Thrown at src/Drivers/Imagick/Modifiers/ProfileModifier.php:25

use ImagickException;
use Intervention\Image\Exceptions\ModifierException;
use Intervention\Image\Interfaces\ImageInterface;
use Intervention\Image\Interfaces\SpecializedInterface;
use Intervention\Image\Modifiers\ProfileModifier as GenericProfileModifier;

class ProfileModifier extends GenericProfileModifier implements SpecializedInterface
{
    /**
     * @throws ModifierException
     */
    public function apply(ImageInterface $image): ImageInterface
    {
        $imagick = $image->core()->native();

        try {
            $result = $imagick->profileImage('icc', (string) $this->profile);
            if ($result === false) {
                throw new ModifierException(
                    'Failed to apply ' . self::class . ', unable to set ICC color profile',
                );
            }
        } catch (ImagickException $e) {
            throw new ModifierException(
                'Failed to apply ' . self::class . ', unable to set ICC color profile',
                previous: $e,
            );
        }

        return $image;
    }
}

View on GitHub (pinned to 5598b9e397)

Solutions

  1. Validate the binary before assignment: an ICC file has the signature 'acsp' at byte offset 36
  2. Use a known-good profile such as sRGB IEC61966-2.1 for web output instead of user-supplied files
  3. For CMYK<->RGB work, convert the colorspace ($image->colorspace(...)) or profileImage in the correct direction rather than swapping profiles on mismatched data
  4. Confirm the LCMS delegate exists: convert -list configure | grep -i lcms, and rebuild/install ImageMagick with lcms if missing

Example fix

// before
$image->setProfile(\Intervention\Image\Colors\Profile::fromPath($uploadedIcc));

// after
$binary = (string) file_get_contents($uploadedIcc);
if (strlen($binary) < 128 || substr($binary, 36, 4) !== 'acsp') {
    throw new RuntimeException('The uploaded file is not a valid ICC profile');
}
$image->setProfile(new \Intervention\Image\Colors\Profile($binary));
Defensive patterns

Strategy: try-catch

Validate before calling

$binary = (string) file_get_contents($iccPath);
$isValidIcc = strlen($binary) >= 128 && substr($binary, 36, 4) === 'acsp';
if (!$isValidIcc) {
    throw new \RuntimeException('Not a valid ICC profile: ' . $iccPath);
}
$image->setProfile(new \Intervention\Image\Colors\Profile($binary));

Type guard

function isValidIccProfile(string $binary): bool
{
    return strlen($binary) >= 128 && substr($binary, 36, 4) === 'acsp';
}

Try / catch

use Intervention\Image\Exceptions\ModifierException;

try {
    $image->setProfile($profile);
} catch (ModifierException $e) {
    // bad binary / delegate missing / colorspace mismatch -> keep original profile and continue
    $logger->warning('Profile apply failed: ' . $e->getPrevious()?->getMessage());
}

Prevention

When it happens

Trigger: $image->setProfile(Profile::fromPath($path)) where the file is not a real ICC profile, or applying a print CMYK profile (e.g. FOGRA/US Web Coated) to an sRGB image without converting first.

Common situations: Letting users upload .icc files and assigning them verbatim; ImageMagick built without the LCMS delegate so profile handling silently degrades; mismatched profile chains when moving assets between print and web pipelines.

Related errors


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