PHP Fatal error: Class Not Found — Composer Autoload Miss
Fix "Class not found" fatal errors by regenerating the Composer autoloader, matching PSR-4 namespace to directory, and clearing the opcache.
Symptoms
- Fatal error: Uncaught Error: Class "App\Service\Mailer" not found
- Works locally but fails on the deployed server
- A newly added class is not found until you manually edit something
Possible causes
- The PSR-4 namespace prefix does not map to the actual directory path
- The optimized autoloader was built before the class was added
- The file case differs from the namespace (case-insensitive FS hides it locally)
Diagnosis steps
Regenerate the autoloader with verbose output
composer dump-autoload -o -vvvInterpretation
Rebuilding the classmap reports which files were scanned and often reveals a wrong path.
Check the namespace-to-directory mapping
composer show -p | grep php && grep -n "psr-4" composer.jsonInterpretation
The psr-4 block must map each namespace prefix to the directory that really holds the class file.
Confirm the file path and case
ls -l src/Service/Mailer.phpInterpretation
On Linux a filename with different case from the namespace fails; verify exact case.
Root cause
Composer resolves classes through its generated autoloader using PSR-4 prefixes. When the prefix, directory, or filename case does not match exactly, or the autoloader is stale, the class cannot be located and PHP raises a fatal not-found error.
Fix
Align the psr-4 mapping with the real directory layout, use the same case on disk as in the namespace, run composer dump-autoload -o after adding classes, and configure deployment to regenerate the autoloader.
Risk note
Running dump-autoload -o with --no-dev in production can drop dev-only classes; verify the environment flags.
Verify the fix
Reload the page or run the command that previously failed and confirm the class instantiates; check composer dump-autoload reports the class in the classmap.
Symptoms
This guide profiles the failure behind “PHP Fatal error: Class Not Found — Composer Autoload Miss”. It walks through the observable symptoms, a reproducible diagnosis path, the underlying root cause, the concrete fix, and how to verify the change and prevent a regression.
Observed symptoms include:
- Fatal error: Uncaught Error: Class “App\Service\Mailer” not found
- Works locally but fails on the deployed server
- A newly added class is not found until you manually edit something
Reproduce and Diagnose
Reproduce the failure in isolation before changing any code. Work through the checks below in order; each one narrows the search space.
Step 1: Regenerate the autoloader with verbose output
composer dump-autoload -o -vvv
Rebuilding the classmap reports which files were scanned and often reveals a wrong path.
Step 2: Check the namespace-to-directory mapping
composer show -p | grep php && grep -n "psr-4" composer.json
The psr-4 block must map each namespace prefix to the directory that really holds the class file.
Step 3: Confirm the file path and case
ls -l src/Service/Mailer.php
On Linux a filename with different case from the namespace fails; verify exact case.
Likely contributors, in order of frequency:
- The PSR-4 namespace prefix does not map to the actual directory path
- The optimized autoloader was built before the class was added
- The file case differs from the namespace (case-insensitive FS hides it locally)
Root Cause
Composer resolves classes through its generated autoloader using PSR-4 prefixes. When the prefix, directory, or filename case does not match exactly, or the autoloader is stale, the class cannot be located and PHP raises a fatal not-found error.
The Fix
Align the psr-4 mapping with the real directory layout, use the same case on disk as in the namespace, run composer dump-autoload -o after adding classes, and configure deployment to regenerate the autoloader.
Watch out: Running dump-autoload -o with –no-dev in production can drop dev-only classes; verify the environment flags.
{
"autoload": {
"psr-4": {
"App\\": "src/"
}
}
}
# after adding App\Service\Mailer
composer dump-autoload -o
# production deploy
composer install --no-dev --optimize-autoloader
Verify and Prevent
Reload the page or run the command that previously failed and confirm the class instantiates; check composer dump-autoload reports the class in the classmap.
Once verified, add a regression test that reproduces the original symptom so the failure cannot silently return.
This class of failure is usually environmental rather than pure logic, so capture the exact command, the environment variables, and the working directory in your bug report. Reproduce it in the smallest possible script, then widen the scope only once the minimal case is understood. A short written checklist for this failure mode saves hours the next time it appears.