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
- Make the file readable by the PHP user: chmod 644 <file> (or chown it to the PHP-FPM user)
- Fix the producer side: set a sane umask or explicit chmod right after the file is created/written
- 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
- Set an explicit umask (0022) in workers that create files consumed by the web server
- chmod 0644 immediately after writing files that other processes must read
- For NFS/shared mounts, align UIDs or use ACLs (setfacl -m u:www-data:r)
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
- Invalid $limit value. Must be int<1, max>
- Failed to open file from path "' . $path . '"
- Can't write to path. Directory "' . $dir . '" is not writabl
- Can't write to path. Existing file " . $path . " is not writ
- Unable to create Intervention\Image\Alignment from "{identif
AI-assisted analysis of Intervention/image@5598b9e397 (2026-08-23).
Data as JSON: /api/errors/e99cc8a1a6a932dc.
Report an issue: GitHub.