Laravel schedule:run is not working when added into the cron job

Stefan Bogdanescu

Founder & Senior Architect · 2026-06-29

Laravel Company
# Fixing the Scheduling Nightmare: Why `schedule:run` Fails in Cron Jobs As senior developers, we often run into frustrating discrepancies between local development environments and production deployment settings. One of the most common pain points revolves around scheduling tasks using Laravel's built-in scheduler, especially when deploying to a server environment managed by cron jobs. The issue you are facing—where running `php artisan schedule:run` via cron executes commands but returns the list of available commands instead of executing your scheduled tasks—is almost always related to the execution environment and how Artisan bootstraps within that context. Let’s dive into why this happens and how we can fix it, ensuring your Laravel scheduler runs reliably on your live server. ## The Root Cause: Environment Discrepancy in Cron When you execute a command directly in your terminal (like PuTTY), your shell environment is fully configured. It knows where to find the `php` executable, the application root, and all necessary environment variables (`PATH`, `$HOME`). However, cron jobs run in a highly restricted, minimal environment. They lack the established context that a standard CLI session has. When you execute `/usr/bin/php /path/to/artisan schedule:run` via cron, PHP executes the command, but it often fails to correctly load the necessary framework context (like finding the `bootstrap/app.php`) or resolve the application's root path correctly within that restricted execution context. Consequently, Artisan defaults to displaying its help message because it cannot properly initialize the application instance needed to process the schedule. ## Solution 1: The Robust Cron Entry Fix The solution lies in ensuring that the cron job explicitly executes the command from the correct working directory and ensures the full path to PHP is used consistently. Relying on relative paths or chaining commands (`&&`) can sometimes lead to unpredictable behavior depending on how the server configures `$PATH`. Instead of relying solely on running `artisan schedule:run`, a more robust method is to call the scheduler directly within the application context, ensuring Laravel knows exactly where it is running from. ### Option A: Using Absolute Paths and Full Context (Recommended) Ensure your cron entry provides the full path to the PHP executable and explicitly points to the application root. This helps prevent environment confusion. **Instead of:** `/usr/bin/php /home/ddsas9rm2f1g/public_html/clowdlink.com/crm/artisan schedule:run` **Try ensuring the command is executed from the project root and using the full path to PHP:** ```cron * * * * * cd /home/ddsas9rm2f1g/public_html/clowdlink.com/crm && /usr/bin/php artisan schedule:run >> /path/to/logs/cron.log 2>&1 ``` Adding `>> /path/to/logs/cron.log 2>&1` is crucial. This redirects all output (both standard output and errors) to a log file. If the command fails, you can check the log file later to diagnose exactly *why* it failed, rather than just seeing a confusing error message in the cron mail. ## Solution 2: Executing Commands Directly (Bypassing `schedule:run`) If your goal is simply to run the commands defined in the schedule *without* running the entire scheduler mechanism every time—which is often safer and faster for cron—you can bypass `schedule:run` entirely and execute the specific command directly. In your case, since you are scheduling a custom command (`update:callLogs`), you should schedule that command directly rather than relying on the general scheduler loop to invoke it. **Modify your Command Kernel:** If you want this task to run every minute, ensure the command itself is scheduled correctly in `app/Console/Kernel.php`: ```php protected function schedule(Schedule $schedule): void { // Schedule the custom command directly $schedule->command('update:callLogs')->everyMinute(); } ``` **Modify your Cron Job:** If you schedule the individual task, your cron job can simply execute that specific command. This removes the dependency on the scheduler running successfully first: ```cron * * * * * cd /home/ddsas9rm2f1g/public_html/clowdlink.com/crm && php artisan update:callLogs >> /path/to/logs/commands.log 2>&1 ``` ## Conclusion The behavior you observed is a classic symptom of environment isolation when moving from a local CLI session to a system scheduler like cron. By treating the cron job as a standalone script—explicitly defining the working directory (`cd`) and ensuring all output is logged (`>> logfile`)—you regain control over the execution context. For production stability, always prioritize logging errors. If the command fails on cron, look at your log file; it will tell you precisely if the problem is application bootstrapping or a missing dependency. Remember that consistent environment management is key to successful deployment, which aligns perfectly with the principles of robust framework usage promoted by resources like [Laravel Company](https://laravelcompany.com).