Almost everything WHMCS does on its own happens inside one scheduled script: crons/cron.php. Invoices are generated there, overdue services are suspended there, reminder emails go out from there, and domain renewals are synced there. When that cron stops, nothing visibly breaks, so the first sign is usually a client asking why they were never invoiced, or a service that should have been suspended weeks ago.
Confirm it is actually the cron
Open Configuration → System Settings → Automation Settings. At the top, WHMCS shows the last run time of the cron. If it is more than ten minutes old, the cron is not running. If it shows a recent time but invoices are still missing, the cron runs but a task inside it fails, which is a different section below.
Then look at Configuration → System Logs → Activity Log and filter for "cron". Every run leaves an entry, and failures leave the error message you need.
The correct cron command
WHMCS 9 wants the script run every five minutes, with PHP's quiet flag:
*/5 * * * * php -q /var/www/vhosts/yourbrand.com/billing.yourbrand.com/crons/cron.phpThree things to get right in that line:
- The path is to
crons/cron.php, not to the oldadmin/cron.phpfrom WHMCS 7. If you moved thecronsdirectory outside the web root (a good idea), the path is wherever you put it, andconfiguration.phpmust contain$crons_dirpointing at it. - The PHP binary must be 8.2 or newer with ionCube loaded. On Plesk the system
phpis often not the one your site uses. Use the handler's full path, for example/opt/plesk/php/8.3/bin/php. - Every five minutes is intended. WHMCS keeps its own schedule internally and only runs the daily tasks once. Running it hourly delays suspensions and ticket escalations.
In Plesk you add this under Scheduled Tasks as a Run a PHP script task, which uses the site's own PHP handler automatically and avoids the wrong-binary problem entirely.
Run it by hand to see the error
The fastest diagnosis is to run the exact command from the cron line in a shell:
/opt/plesk/php/8.3/bin/php -q /var/www/vhosts/yourbrand.com/billing.yourbrand.com/crons/cron.phpA healthy run prints nothing. The failures below print something.
The six failures we see most
1. ionCube Loader is not installed for this PHP. The cron uses a different PHP than the web server. Fix the binary path as above, or enable ionCube for that handler in Plesk.
2. Could not open input file. The path is wrong, usually because the crons directory was moved during hardening but the cron line was not updated.
3. Nothing runs and the log is empty. The cron entry exists but under a different system user than the one that owns the files, so PHP cannot read configuration.php. In Plesk, create the task under the subscription that owns the site, not as root.
4. Cron job runs but tasks fail with a licence error. WHMCS checks the licence on each run. If the URL in the licence does not match the URL the cron reports, the run aborts. Re-issue the licence for the correct domain from your WHMCS account or, on a bundled licence, tell us and we re-issue it.
5. Invoices are generated but no emails go out. The cron is fine; email is the problem. See WHMCS not sending emails.
6. The cron takes minutes and times out. Usually a registrar or server module waiting on a slow API. Under Automation Settings you can move heavy tasks (domain sync, usage stats) to their own schedule so the five-minute run stays light.
The POP3 cron is separate
If support departments import email replies from a mailbox, that is a second cron:
*/5 * * * * php -q /var/www/vhosts/yourbrand.com/billing.yourbrand.com/crons/pop.phpWithout it, WHMCS emails every administrator a "POP cron did not run" warning, and ticket replies sent by email never appear. Give it the same PHP binary and the same five-minute schedule.
Verify and move on
After fixing, wait five minutes and refresh Automation Settings. The last-run time should update, and the Activity Log should show a clean entry. Then run the daily tasks once by hand to catch up on anything missed:
/opt/plesk/php/8.3/bin/php -q /path/to/crons/cron.php all --forceThat generates the invoices and reminders that should have gone out while the cron was down. Warn clients first if it has been down for a long time: they will receive everything at once.
On VPSPioneer reseller plans with the WHMCS licence included, we set both cron jobs up as part of the install and monitor the last-run time, so a stalled cron is our alert, not your client's complaint.