Common causes
- 'No such file or directory': vendor/ was never created on this server because composer install was not run or failed
- vendor/ was uploaded by FTP but the upload was incomplete, so autoload.php or files it includes (vendor/composer/*, polyfill bootstrap files) are missing
- 'Permission denied': vendor/ was uploaded or installed by another user (e.g. root) and the PHP user cannot read it
- 'open_basedir restriction in effect': vendor/ sits above the allowed path on shared hosting
- The document root was moved (e.g. Laravel's public/ became public_html) so the relative ../vendor path now points to the wrong place
- A deployment excluded vendor/ through .gitignore, .cpanel.yml or an rsync exclude
How to fix it
- Read the reason after 'Failed to open stream'. 'No such file or directory', 'Permission denied' and 'open_basedir restriction' have different fixes. Also note the full resolved path PHP tried.
- Run composer install where composer.json lives. In the project root, run composer install --no-dev --optimize-autoloader. Without SSH, use the host's Composer feature or run it locally with the same PHP version and upload vendor/ as a ZIP, then extract it on the server.
- Re-upload vendor/ as one archive. Uploading thousands of files over FTP often silently skips some. Compress vendor/ locally, upload the ZIP and extract it in File Manager, then compare file counts.
- Fix ownership and permissions. Files should be owned by the site's user with 644 for files and 755 for directories, e.g. find vendor -type d -exec chmod 755 {} + and find vendor -type f -exec chmod 644 {} +. Never use 777.
- Fix the path after moving public files. If you moved index.php into public_html, update the require to point at the real location, e.g. require __DIR__ . '/../laravel-app/vendor/autoload.php';.
- Check open_basedir. If the message mentions open_basedir, keep vendor/ inside your home directory or ask the host to add the project path to open_basedir.
public_html/index.php (Laravel app outside public_html)
<?php
// project lives in /home/user/laravel-app, public files in /home/user/public_html
require __DIR__ . '/../laravel-app/vendor/autoload.php';
$app = require_once __DIR__ . '/../laravel-app/bootstrap/app.php'; How to stop it happening again
- Make composer install part of every deployment instead of uploading vendor/ by FTP
- Build require paths from __DIR__, never from the current working directory
- After a deploy, run a quick smoke test that loads the home page or php artisan --version