A FOSSBilling installation that throws a 500 or a blank page rarely fails without leaving a trail. The challenge on shared hosting is that the trail is scattered across several places: the web server response, the PHP error log in your document root, the FOSSBilling application log, and sometimes the database itself. FOSSBilling runs on a Symfony-influenced structure with its own front controller, template cache, and configuration file, so an error that surfaces as a generic "Something went wrong" message in the browser almost always has a precise, readable cause underneath. The goal here is to switch off the friendly mask, capture the real exception text, and map that text to a fix you can apply from cPanel Jupiter or DirectAdmin Evolution without any root access.

Reading the right logs before you change anything

Before touching configuration, collect evidence. FOSSBilling writes to three distinct layers, and each answers a different question.

The first is the PHP error log produced by LiteSpeed for your account. On both cPanel and DirectAdmin this appears as an error_log file in the directory where the fault occurred — usually the document root (for example /home/youruser/public_html/error_log) or inside a subfolder if FOSSBilling lives in one. Open it with File Manager, scroll to the bottom, and read the most recent timestamped entry. A fatal error here looks like PHP Fatal error: Uncaught Error: Class "..." not found in /home/youruser/public_html/vendor/... followed by a stack trace. That stack trace is the single most valuable piece of information you have; the top line is where execution stopped, and the lines beneath show how it got there.

The second layer is FOSSBilling's own application log. FOSSBilling stores logs under data/log/ relative to its install root — the main file is data/log/application.log. This captures exceptions the application caught and handled, including database connection failures, failed module loads, and mail or gateway errors that never reach the PHP error log. If the browser shows a styled FOSSBilling error page rather than a raw white screen, the matching detail is almost always written here.

The third layer is the web server response itself. In cPanel, open Metrics → Errors to see the last few hundred server error lines, or in DirectAdmin check System Info & Files → Error Log. This view helps when the request never reaches PHP at all — for instance a malformed .htaccess directive, which produces an Invalid command or 500 Internal Server Error with no corresponding PHP entry. If your PHP error_log is empty but the browser still shows a 500, suspect .htaccess or a file-permission problem rather than application code.

Capture all three, note the exact timestamps, and reproduce the error once in the browser so you can match the newest log line to your action. Only then start changing settings.

Enabling FOSSBilling debug mode and verbose PHP errors

FOSSBilling ships with production error handling on, which deliberately hides stack traces from visitors. To see the real exception, enable debug mode in the configuration file. Open config.php in the FOSSBilling root with File Manager's editor. Locate the 'debug' key and set it to true, and confirm the log level is verbose enough:

return [
    'debug' => true,
    'debug_and_monolog' => true,
    'log_stacktrace' => true,
    'log_level' => 'DEBUG',
    // ... existing url, db, and security_salt values unchanged ...
];

Save, reload the failing page, and FOSSBilling will now print the full exception class, message, file, and line directly in the browser or write a far more detailed entry into data/log/application.log. Treat this as a temporary diagnostic state: debug mode can reveal file paths and query fragments, so revert 'debug' to false the moment you finish.

If the page is still blank with no FOSSBilling output at all, the failure is happening before the application boots, which means PHP itself is suppressing the error. Force PHP to surface it with a .user.ini file in the FOSSBilling document root. This file is read by the LiteSpeed PHP handler on CloudLinux and needs no restart beyond the few-minute refresh window:

display_errors = On
display_startup_errors = On
error_reporting = E_ALL
log_errors = On
memory_limit = 256M
max_execution_time = 120

Confirm your active PHP version in cPanel MultiPHP Manager or the DirectAdmin Select PHP Version tool. FOSSBilling current releases need PHP 8.1 or newer; running it on 8.0 or an older branch produces fatal syntax or type errors deep in vendor/ that look baffling until you check the version. Switch the domain to a supported interpreter from the same screen, then reload.

Mapping common exceptions to concrete fixes

With real output in hand, most FOSSBilling faults fall into a small set of patterns you can resolve from your account tools.

Missing or disabled PHP extension. A message such as Uncaught Error: Call to undefined function curl_init() or complaints about intl, mbstring, pdo_mysql, openssl, or gd means a required extension is not loaded for your selected PHP version. In cPanel open Select PHP Version → Extensions (the PHP Selector under CloudLinux) and tick the missing module; in DirectAdmin use the equivalent extensions tab. These toggle per PHP version, so enabling intl on 8.1 does nothing if your domain runs on 8.2.

Database connection or query failure. Entries like SQLSTATE[HY000] [1045] Access denied or Unknown database point at the credentials block in config.php. Verify the 'host', 'name', 'user', and 'password' under the 'db' array against what phpMyAdmin shows. If you recently migrated, the database user may need reassigning in cPanel MySQL Databases → Add User To Database with All Privileges. A Base table or view not found error after an upgrade usually means the schema migration did not complete — re-run the updater from the FOSSBilling admin or restore the pre-upgrade database dump through phpMyAdmin's Import tab.

Corrupt template or cache. Twig-related exceptions or stale admin pages after an update are resolved by clearing the compiled cache. Delete the contents of data/cache/ (not the folder itself) in File Manager; FOSSBilling regenerates it on the next request.

Permission and ownership faults. failed to open stream: Permission denied against data/ means the writable directories lost their mode. Set data/, data/cache/, data/log/, and data/uploads/ to 755 via File Manager's Permissions dialog, and ensure files are 644. Never use 777 on shared hosting; LiteSpeed runs scripts as your user, so 755 is sufficient and keeps the account within suPHP/CloudLinux policy.

Broken .htaccess. If Metrics → Errors shows an Invalid command line, a module directive in your .htaccess is not available under LiteSpeed. Comment the offending line with a leading # or restore the stock FOSSBilling rewrite block, which only needs the standard front-controller redirect to index.php.

Verifying the fix and returning to a safe state

After each change, reload the exact URL that failed and re-check the newest line in data/log/application.log and the account error_log. A clean reload with no fresh timestamped error is your confirmation — not merely the page rendering, since FOSSBilling can display a cached page while still logging a background exception. Work one variable at a time so you can attribute the result; toggling an extension, clearing the cache, and editing credentials all at once hides which action solved the problem.

Once the error is gone, undo the diagnostic settings. Set 'debug' => false in config.php, remove or set display_errors = Off in .user.ini, and keep log_errors = On so future faults still record quietly without exposing traces to visitors. Delete any phpinfo test files you created. If the fix involved a PHP version change, run a full pass through the billing admin — invoice generation, a test checkout, and the cron trigger at bin/fossbilling-cron — because version jumps occasionally surface a second dormant extension requirement only under those workflows. The same disciplined log-first method applies to related billing platforms; the staging and rollback approach in this Blesta upgrade guide pairs well with it when an update is what triggered the 500 in the first place.