Ffile2fix
Sign in Get started

Fix: require vendor/autoload.php Failed to open stream

Warning: require(/home/user/public_html/vendor/autoload.php): Failed to open stream: No such file or directory in /home/user/public_html/index.php on line 5

PHP could not read Composer's autoloader at the path in the require statement, and the reason after the colon tells you why: the file is missing, unreadable, or outside the folders PHP may access. It is followed by a fatal error because nothing else can load without the autoloader.

Also appears as: Warning: require_once(vendor/autoload.php): Failed to open stream: No such file or directory · Warning: require(/var/www/app/public/../vendor/autoload.php): Failed to open stream: Permission denied · Warning: require(): open_basedir restriction in effect. File(/home/user/vendor/autoload.php) is not within the allowed path(s) · Warning: require(/var/www/app/vendor/composer/../symfony/polyfill-mbstring/bootstrap.php): Failed to open stream: No such file or directory

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

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. 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';.
  6. 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

Frequently asked questions

autoload.php exists but the error names a file inside vendor/composer. Why?

autoload.php itself loaded, but one of the files Composer registered (a polyfill or helper file) is missing. That means vendor/ is incomplete or out of date; delete vendor/ and run composer install again.

Can I just copy vendor/ from my computer?

Yes, if your local PHP version and extensions match the server and you install with --no-dev. Upload it as a single archive so no files are skipped.

Why does it work in the browser but not in cron?

Cron runs from a different working directory, so relative paths like 'vendor/autoload.php' resolve elsewhere. Use __DIR__-based paths.