Marketing Software
Enable PHP Error Logging in cPanel: Step-by-Step Guide
Stop guessing when PHP breaks. This cPanel-focused guide shows how to enable production-safe error logs, choose the right path and permissions, rotate files, add alerts, and fix WordPress-specific issues - fast.
If your PHP app goes dark at 3 a.m., you don’t want a guessing game. You want a log file that tells you exactly what failed, when, and why. On shared hosting, that usually means cPanel. This guide shows you how to enable PHP error logging in cPanel the right way - production-safe settings, the correct log path outside web root, rotation to avoid disk bloat, quick analysis tips, and WordPress specifics. No agency needed, no yak shaving. Just a clean setup that helps you fix issues before they cost you leads and revenue.
Why PHP error logging matters for uptime, SEO, and revenue
Every error in production has a price. A fatal error during checkout blocks orders. A deprecated function on your signup page tanks form submissions. A notice spammed to the browser can leak path data and spook customers. Without structured logging, you’re blind - and blind troubleshooting is expensive in both time and lost conversions.
Search performance also suffers. If PHP errors bubble up as 500 responses, Googlebot will back off. Enough server errors and your crawl rate drops, which slows indexing and can suppress rankings. Detailed error logs help you quickly trace the root cause and stabilize the site - protecting both organic visibility and paid landing page Quality Scores.
Finally, logs make ops repeatable. Instead of “it just broke,” you get a timeline. You can see the exact plugin update before the first fatal, the memory exhaustion under load, or the missing file path in a deploy. That turns firefighting into a playbook - faster MTTD and MTTR, fewer late-night calls, and more consistent revenue.
How PHP error logging actually works
PHP exposes three levers you’ll use in cPanel: error_reporting (which error levels are recorded), display_errors (whether errors print to the browser), and log_errors (whether errors are written to a file). You’ll also set error_log (the log file path) and, ideally, date.timezone so timestamps match your ops calendar.
At runtime, PHP classifies issues by severity: E_ERROR, E_WARNING, E_PARSE, E_NOTICE, E_DEPRECATED, and others. The bitmask you assign to error_reporting enables or excludes these. In development you want everything (E_ALL). In production you still want E_ALL logged but generally exclude notices and, if you’re stable, some deprecations - while always keeping display off.
cPanel environments vary. Some use DSO, others CGI/FastCGI, others LSAPI with LiteSpeed. That determines whether .htaccess, .user.ini, or a domain-level INI editor is authoritative. The good news: in modern cPanel with MultiPHP, you can set these cleanly per domain without hacking core files.
Where to control PHP settings in cPanel
There are three common places for PHP config in cPanel: the MultiPHP INI Editor (domain-level), the .user.ini file (per-directory, read by CGI/FPM/LSAPI), and .htaccess (when PHP runs as an Apache module with php_value directives allowed). Which one works depends on your host’s handler and permissions model.
Start with cPanel → MultiPHP INI Editor. It’s the cleanest way to set error_reporting, log_errors, display_errors, error_log, and date.timezone per domain. If your host disabled it or you need a directory override (e.g., for a subdirectory app), use .user.ini.
If your stack still honors .htaccess for PHP directives, you can set values there with php_flag and php_value. But beware: with FastCGI/FPM this won’t work; use .user.ini instead. When in doubt, create a phpinfo() page and check “Loaded Configuration File” and “Additional .ini files parsed.”
Step-by-step: enable PHP error logging with MultiPHP INI Editor
Here’s the clean, host-friendly path. You’ll set a safe error policy, route logs outside web root, and make sure timestamps are accurate. Plan 10–15 minutes.
1) Open cPanel and find “MultiPHP INI Editor.” Choose “Editor Mode.” From the domain dropdown, select the site you’re configuring. You should see (or can paste) a domain-specific php.ini template.
2) Ensure production-safe visibility: set display_errors = Off. You never want raw errors in the browser for customers or bots. This closes a common info disclosure vector and avoids broken-looking pages.
3) Enable logging: set log_errors = On. This tells PHP to write issues to a file even when they aren’t printed.
4) Choose a log file path outside public_html. For example, error_log = "/home/USERNAME/php-logs/site-error.log". Create the php-logs folder in File Manager if it doesn’t exist. Keeping logs outside web root prevents anyone from downloading them.
5) Set a comprehensive but sane reporting level. In production, a common mask is error_reporting = E_ALL & ~E_NOTICE & ~E_STRICT. If you’re actively migrating from older code, keep deprecation messages in the log to plan upgrades: E_ALL & ~E_NOTICE & ~E_STRICT still includes E_DEPRECATED on PHP 8; refine as needed.
6) Align timestamps: set date.timezone = Region/City (e.g., date.timezone = Asia/Dubai). Misaligned logs slow down triage when your team spans time zones.
7) Save changes. Then create a quick test: make a file like php-log-test.php under a non-indexed path and trigger a warning (e.g., include a non-existent file). Load it once. Confirm the entry lands in your site-error.log.
Alternative methods: .user.ini, .htaccess, and code-level overrides
If MultiPHP INI Editor is disabled or you need a per-directory override (like a subapp or staging folder), use .user.ini. This works with CGI/FPM/LSAPI handlers and cascades by directory.
Create .user.ini in the application directory and add:
display_errors = Off
log_errors = On
error_reporting = E_ALL & ~E_NOTICE & ~E_STRICT
error_log = "/home/USERNAME/php-logs/app-error.log"
With Apache module setups that allow it, .htaccess can set PHP flags. Note that many modern hosts disallow these for security or because PHP runs as FPM. If allowed, use:
php_flag display_errors Off
php_flag log_errors On
php_value error_reporting 32767
php_value error_log "/home/USERNAME/php-logs/app-error.log"
Finally, for temporary debugging without touching INI files, you can prepend in a single script (not recommended as a permanent policy):
<?php
ini_set('display_errors', '0');
ini_set('log_errors', '1');
ini_set('error_log', '/home/USERNAME/php-logs/runtime-error.log');
error_reporting(E_ALL & ~E_NOTICE & ~E_STRICT);
?>
Production-safe settings: what to log, what not to show
Rule one: never show raw PHP errors to end users. display_errors = Off belongs in every production environment. If you need on-screen details in staging, protect it with HTTP auth or IP allowlists. Browsers are for customers; files are for engineers.
Rule two: log broadly enough to catch what matters. E_ERROR, E_WARNING, and E_PARSE are table stakes. Including deprecations in production logs is valuable during PHP version upgrades - it surfaces landmines before they become fatals. If the log volume explodes, tune out E_NOTICE first.
Rule three: don’t suppress with the error control operator (@). It hides symptoms and makes root causes harder to find. If a vendor library uses it, log a feature request or wrap calls with explicit checks. Logging is the map; don’t blur it.
Choose a safe log path and permissions
Keep logs out of public_html. A common pattern is /home/USERNAME/php-logs/ with a single file per app: site-error.log. If you must keep them under web root, block access with .htaccess and confirm it works behind any proxy/CDN you use.
Permissions should be restrictive but writable by PHP’s user. On most cPanel setups: directory 0750 and files 0640 or 0644 are fine. Avoid 0777. If the log doesn’t write, check ownership (often the cPanel user) and the PHP handler. File Manager’s permissions UI can adjust these quickly.
Name logs clearly so rotation scripts can target them. If you have multiple sites, use consistent naming: domain-tld-error.log. Consistency pays off when you’re triaging multiple properties.
Rotate and monitor logs to avoid disk bloat
Left alone, error logs can balloon and hit disk quotas, which can break email and site writes. Rotation keeps file sizes under control and preserves a history. While system logrotate typically doesn’t manage user-defined PHP logs in shared hosting, you can DIY with a cPanel cron job.
Example rotation script (bash) to keep the last 7 days of logs and compress older ones. Save as /home/USERNAME/bin/rotate-php-logs.sh and make it executable.
#!/bin/bash
LOGDIR="/home/USERNAME/php-logs"
MAXSIZE=$((50*1024*1024)) # 50MB
find "$LOGDIR" -type f -name "*.log" | while read f; do
size=$(stat -c%s "$f")
if [ $size -ge $MAXSIZE ]; then
ts=$(date +%Y%m%d-%H%M%S)
mv "$f" "${f}.${ts}"
gzip "${f}.${ts}"
touch "$f"
chmod 640 "$f"
fi
done
find "$LOGDIR" -type f -name "*.log.*.gz" -mtime +7 -delete
Set a cron in cPanel (e.g., hourly or daily) to run that script. Tail before and after to confirm rotation works. If your host disallows executables, you can write a small PHP rotator that renames and gzips files with gzencode().
Read and analyze logs fast
When something breaks, you want the last 100 lines, not a 200MB download. In File Manager, use “View” and scroll to the bottom for recent entries. Better, if SSH is enabled, run tail -n 100 -f /home/USERNAME/php-logs/site-error.log while reproducing the issue to see events in real time.
To filter noise, pipe through grep. For example, grep -i "fatal" or grep -i "deprecated". Combine with timestamps to isolate a failure window: grep "2026-09-06" site-error.log. Simple filters cut debugging time dramatically.
Don’t forget context. Pair error timelines with deploy logs, plugin updates, and traffic spikes. A “memory exhausted” at 11:59 a.m. might coincide with a promo email send. Error logs are one lens; pair them with ops calendars.
Troubleshooting when PHP won’t write logs
If your log file stays empty, triple-check which configuration file is in charge. Drop a phpinfo() file in the same directory as the failing script and note the “Loaded Configuration File,” “Additional .ini files parsed,” and the value of error_log. If PHP is reading a different path than you think, fix that first.
Next, check filesystem issues. Does the directory exist? Are permissions sufficient? Can PHP’s user create and write to the file? Try creating the log file manually via File Manager and set permissions to 0640 or 0644. Ensure you didn’t point error_log to a directory path by mistake - it must be a file path.
Finally, look for overrides in code or .htaccess. A stray ini_set() could be turning logging off. Some CMS configs (like WordPress) manage their own logging flags; align them with your global policy so you’re not writing to two locations or suppressing critical errors.
Security, compliance, and privacy considerations
Logs can contain sensitive details: file paths, query strings, even user input echoed in error messages. Treat them as confidential. Keep logs outside web root or block access with .htaccess, and limit read permissions to your ops staff.
Mask PII when possible. If your code logs full request payloads, scrub email addresses or IDs before writing. Avoid logging secrets: no API keys, no passwords, no tokens. Your incident response plan should include procedures for sanitizing historical logs if a breach occurs.
Retention matters. Keep what you need for troubleshooting and audits, then purge. A 7–30 day window is common for small sites; regulatory environments may require more. Rotation scripts help enforce this without manual cleanup.
WordPress and popular CMS specifics
WordPress ships its own toggles. In wp-config.php, you’ll see or can add: define('WP_DEBUG', false); define('WP_DEBUG_LOG', true); define('WP_DEBUG_DISPLAY', false);. By default, WP_DEBUG_LOG writes to wp-content/debug.log. For better hygiene, redirect it to your non-public logs directory with define('WP_DEBUG_LOG', '/home/USERNAME/php-logs/wp-debug.log');.
If a plugin update sparks fatals, you’ll likely see stack traces pointing to wp-content/plugins/plugin-name/.... Use logs to identify the exact version and line. Roll back, open a ticket with the vendor, and test in staging before re-deploying. Don’t rely on on-screen notices; keep WP_DEBUG_DISPLAY off in production.
Other CMSs (Laravel apps, Magento, Drupal) have framework-level logs too. Keep them, but do not let them replace PHP’s own error log. The PHP log often catches bootstrap-level issues that never reach the framework.
Operator vs agency: get this done without the overhead
You don’t need a big agency to set up error logging, rotation, and alerts. A senior operator can handle the stack end to end - server settings, WordPress config, and a simple cron monitor - in under an hour. That’s the operating model we use: one accountable builder who ships, not a layer of account managers creating tickets.
At Anton Chisliuk · AI Marketing Ops, we run marketing and the systems behind it - from GTM and AI SEO content to the plumbing that keeps your site stable when campaigns hit. Proof matters: on Cleverence (B2B SaaS), the stack we built scaled from 0 to 80K organic visits/month and 2K inbound leads/month, with paid CPL in the $2–6.50 range. Stable sites convert better; clean logs make “stable” repeatable.
If that operator model sounds like the way you want to work - leads, sales, content, and systems, one senior operator - read how we operate on our about page. No fluff; just how we build and measure.
Time, cost, and decision checklist
Time: 15–45 minutes to implement logging, rotation, and a basic alert. Add 15 minutes to wire WordPress to a non-public path. If SSH is disabled, plan a few extra minutes for File Manager workarounds.
Cost: $0 on most cPanel hosts. Rotation via cron is free. The only “cost” is a few megabytes of disk per week, which rotation caps. If you outgrow shared hosting, migrate the same policy to VPS with system logrotate.
Decision checklist: Is display_errors off? Are logs outside public_html? Do permissions avoid 0777? Is rotation in place? Do you have an alert for “Fatal error” spikes? If you’d rather not pay the agency tax for basics like this, compare the model you’re using; the operator vs agency trade-offs are real on both cost and speed. For a sense of steady-state costs on everything else marketing ops, see our pricing.
Automate basic alerts (optional but recommended)
Logs are only useful if someone looks. Add a tiny cron-driven script that scans the log for new fatals and emails you or posts to Slack. It’s not Datadog, but it will catch a broken checkout within minutes.
Example PHP snippet to run every 5–10 minutes. It stores the last read byte offset to only email new events:
<?php
$log = '/home/USERNAME/php-logs/site-error.log';
$state = '/home/USERNAME/php-logs/site-error.state';
$pos = file_exists($state) ? (int)file_get_contents($state) : 0;
$fh = fopen($log, 'r');
if ($fh) {
fseek($fh, $pos);
$new = '';
while (!feof($fh)) { $new .= fgets($fh); }
$newPos = ftell($fh);
fclose($fh);
file_put_contents($state, $newPos);
$matches = [];
foreach (explode("\n", $new) as $line) {
if (stripos($line, 'fatal') !== false) { $matches[] = $line; }
}
if ($matches) {
mail('you@example.com', 'PHP Fatal errors detected', implode("\n", $matches));
}
}
?>
Set a cron: “Every 10 minutes” → /usr/bin/php -d detect_unicode=0 /home/USERNAME/bin/check-php-errors.php. Swap email for a webhook post if you prefer Slack. Keep it simple so it never becomes the next thing to debug.
Conclusion
PHP error logging in cPanel isn’t “nice to have.” It’s your early warning system for issues that cost you sales and rankings. The right setup is simple: display off, logging on, logs outside web root, rotation scheduled, and a lightweight alert. Do it once, document it, and stop guessing when something breaks.
If you want a senior operator to audit your current setup and close gaps across hosting, analytics, and funnels, book a quick, no-pitch Growth Audit. It’s the fastest way to see where errors - technical or strategic - are leaking pipeline.
Article by Anton Chisliuk - AI-first marketing operator.
FAQs
- Should I set error_reporting to E_ALL in production?
Yes, with nuance. Log broadly in production but keep display_errors off. If volume is high, exclude E_NOTICE (and sometimes E_STRICT) first. Keep deprecations during PHP upgrades so you see future breakage coming.
- Where should the PHP error log live in cPanel?
Use a folder outside web root, e.g., /home/USERNAME/php-logs/site-error.log. If you must keep it under public_html, block access with .htaccess and confirm the block works through your CDN or proxy.
- Why is my error log empty even though I set log_errors = On?
Likely causes: wrong config file (check phpinfo()), invalid error_log path (directory doesn’t exist or you pointed to a directory, not a file), permissions/ownership mismatch, or a code-level ini_set() turning logging off later in execution.
- Is it safe to enable display_errors temporarily?
Only in staging or behind IP/HTTP auth. Never in public production. Displayed errors leak paths and sometimes data. Use the log file to debug on production and replicate in a protected staging environment.
- How big is too big for an error log?
Anything over 50–100MB is unwieldy on shared hosting. Rotate at or before that size. A simple cron script that renames and gzips the file keeps it manageable without manual work.
- Can I have multiple error logs for different apps under one cPanel account?
Yes. Point each app (or subdomain) to its own error_log path. This isolates noise and makes troubleshooting faster. Keep them all in a single top-level php-logs folder for consistency and rotation scripts.
- How do I read the last lines without downloading the file?
If you have SSH, use tail -n 100 /home/USERNAME/php-logs/site-error.log. Without SSH, open File Manager, click “View,” and scroll to the bottom; or write a small PHP viewer that reads the last N bytes. Avoid leaving viewers accessible in public.
- What about WordPress debug.log vs PHP’s error_log?
Use both, but route them to the same non-public folder. WordPress’s WP_DEBUG_LOG captures application-level notices; PHP’s error_log catches bootstrap/runtime errors. Align retention and rotation for both files.
- Will enabling logging slow down my site?
Negligibly. Disk writes are minimal unless you’re logging a flood of notices. If you notice performance hits, you’re likely logging too much noise (e.g., E_NOTICE) or a hot code path is erroring repeatedly - which you should fix anyway.
- Do I need a third-party log service?
Not on day one. For most cPanel sites, a local log with rotation and a cron-based email alert is enough. If you run distributed apps or need search/retention across many servers, then consider a centralized log solution.
Written by
Anton Chisliuk
Founder & Lead Operator · AI Marketing Operator
Anton Chisliuk is a GTM Engineer and Marketing Systems Architect. He built Cleverence's AI-native revenue OS (88 Make blueprints, MCP hub, 0→200K organic, 2.2K leads/mo) and now delivers outsourced GTM Engineering — CRM, automation, SEO, outbound — for growth-stage businesses via aimrktops.com.
About Anton →Ready to fix this — for real?
Book a free Growth Audit. No sales deck — a 30-minute conversation about your pipeline, stack, and what to ship first.