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

Unable to analyze image colors

Error message

Unable to analyze image colors

What it means

This FileNotReadableException is thrown by filePathFromSplFileInfoOrFail() when everything else checks out (directory exists, file exists, is a regular file, directory is readable) but is_readable($path) on the file itself returns false. The PHP process cannot open the file for reading, typically due to file ownership/mode.

Source

Thrown at src/Analyzers/DominantPaletteAnalyzer.php:92

        $palette = new Palette();
        $minClusterSize = (count($points) * self::MIN_CLUSTER_SIZE_PERCENT) / 100;
        $colorspace = $image->colorspace();

        foreach ($clusters as $cluster) {
            // filter out very small clusters
            if ($cluster['size'] < $minClusterSize) {
                continue;
            }

            try {
                $palette->addColor(
                    // convert centroids back to original colorspace
                    (new OklabColor(...$cluster['centroid']))->toColorspace($colorspace),
                    $cluster['size'],
                );
            } catch (InvalidArgumentException $e) {
                throw new AnalyzerException('Unable to analyze image colors', previous: $e);
            }
        }

        // palette has already a limit of k and is already sorted by cluster size
        return $palette;
    }

    /**
     * Transform color to flattened oklab color channel triples which can be used for clustering.
     *
     * @param Generator<ColorInterface> $colors
     * @throws AnalyzerException
     * @return array<array{float, float, float}>
     */
    private function clusterableColors(Generator $colors): array
    {
        $clusterable = [];
        foreach ($colors as $color) {

View on GitHub (pinned to 5598b9e397)

Solutions

  1. Make the file readable by the PHP user: chmod 644 <file> (or chown it to the PHP-FPM user)
  2. Fix the producer side: set a sane umask or explicit chmod right after the file is created/written
  3. Verify with: sudo -u www-data test -r /path/to/file && echo ok

Example fix

// before: file written by root with 0600, web server cannot read it
file_put_contents($path, $blob); // umask 0077

// after: ensure group/world readability
file_put_contents($path, $blob);
chmod($path, 0644);
Defensive patterns

Strategy: validation

Validate before calling

if (!is_readable($splFileInfo->getPathname())) {
    // cannot be read by current PHP user
    throw new \RuntimeException('Image file unreadable, check ownership/mode: ' . $splFileInfo->getPathname());
}
$image = $manager->read($splFileInfo);

Try / catch

use Intervention\Image\Exceptions\FileNotReadableException;

try {
    $image = $manager->read($file);
} catch (FileNotReadableException $e) {
    if (str_contains($e->getMessage(), 'is not readable')) {
        chmod($file->getPathname(), 0644); // attempt repair, then retry once
        $image = $manager->read($file);
    }
}

Prevention

When it happens

Trigger: ImageManager::read(new SplFileInfo($path)) on a file with mode 0600 owned by another user; files created by root during deployment that the web server user must later read; attachments uploaded through a different service with restrictive umask (0066 result); files on a mounted share with ACLs denying the PHP user.

Common situations: Mixed CLI/web workflows: artisan commands or cron jobs running as root produce files the php-fpm user cannot read; SCP/SFTP uploads defaulting to 0600; NAS/NFS mounts with mismatched UIDs; shared hosting where the account user differs from the PHP process user.

Related errors


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