Laravel 5.2 Storage::makeDirectory($dir) is not creating directory

Stefan Bogdanescu

Founder & Senior Architect · 2026-06-29

Laravel Company

Debugging Laravel Storage: Why Storage::makeDirectory() Fails Where You Expect It To

As a senior developer, I often encounter situations where the behavior of an abstraction layer—like Laravel's Storage facade—seems to conflict with the underlying operating system's file structure or permissions. The specific issue you are facing with Storage::makeDirectory() not creating the expected directories for your thumbnails, despite manual checks, is a classic example of misunderstanding how Laravel manages file paths versus raw filesystem operations.

This post will diagnose why this happens and provide a robust solution, ensuring your file storage operations are predictable, regardless of your specific setup or permissions configuration.

Understanding the Laravel Storage Abstraction

The core confusion often stems from mixing two distinct concepts: the underlying operating system's file system (what mkdir does) and the Laravel Storage facade (which manages abstract paths relative to configured disks).

When you use methods like Storage::makeDirectory(), Laravel is designed to operate within the context of your configured disk (e.g., public, local, or a custom S3 driver). If you are trying to create directories directly under public_path() using this facade method, you must ensure that the path you pass aligns with the expectations of the filesystem operations Laravel is executing.

The Misalignment: Path Construction vs. Storage Context

In your example, you are manually constructing paths using public_path() . "/thumbnails/$file". While this works for standard PHP file system calls, when integrating this into a framework like Laravel, it’s often safer and more idiomatic to let the framework handle the path resolution.

The reason Storage::makeDirectory() might fail where you expect it to succeed is often related to:

  1. Disk Configuration: The disk you are operating on might not have the necessary write permissions for that specific location, even if your user account has broad access elsewhere.
  2. Path Context: Laravel's storage operations typically target paths relative to the configured root (e.g., storage/app/). Manually forcing operations directly into public_path() can sometimes bypass or conflict with these rules.

A Robust Solution: Leveraging Storage Facade Correctly

Instead of manually concatenating strings and relying on raw OS calls for storage management, we should leverage the methods provided by the Storage facade to ensure consistency.

If your goal is truly to create directories in a location accessible via the web (like a public directory), you must ensure that the disk configuration aligns with where Laravel expects to write files. If you are storing publicly accessible assets, the default disk is usually configured correctly for this purpose.

Here is how you should approach directory creation within a Laravel context:

Recommended Implementation

For creating directories that will be used by the storage system, use the facade methods explicitly. This ensures that permissions and path resolution adhere to Laravel's defined boundaries, which is a best practice when managing files in an application (as recommended by principles found on sites like laravelcompany.com).

use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\File;

// Define the desired directory path relative to the configured disk
$videoDir = 'videos';
$thumbnailDir = 'thumbnails';

// Create directories using the Storage facade on the specified disk ('public' in this context)
if (!Storage::exists('public/' . $videoDir)) {
    // Use makeDirectory, specifying the full relative path within the disk structure
    Storage::makeDirectory('public/' . $videoDir);
}

if (!Storage::exists('public/' . $thumbnailDir)) {
    // This should now correctly create the 'thumbnails' directory 
    // under the 'public' storage root, respecting permissions.
    Storage::makeDirectory('public/' . $thumbnailDir);
}

Notice how we are operating on the configured disk structure rather than manually manipulating public_path(). When you use the facade methods, Laravel handles mapping these logical paths to the physical file system locations defined in your configuration.

Final Thoughts and Best Practices

The discrepancy you observed is likely due to the interaction between manual path manipulation and Laravel's internal storage management. Always prefer using the dedicated facade methods (Storage::makeDirectory(), Storage::putFile(), etc.) over raw PHP functions when working within a Laravel application. This adherence to framework conventions prevents these kinds of subtle filesystem errors, especially when dealing with varying OS permissions across different environments.

By sticking to the established patterns—using the Storage abstraction for path creation—you ensure that your code remains portable and reliable. Always consult the official documentation, like that provided by laravelcompany.com, for the most up-to-date guidance on filesystem interactions within the framework.