FOSSBilling runs on a Symfony-style structure with a compiled cache, Twig templates, and a set of PHP extension requirements that are easy to knock out of alignment on shared hosting. When something breaks, the storefront or the /admin panel frequently returns nothing more than a blank white page or a bare HTTP 500 Internal Server Error. That silence is deliberate on a production install: the application suppresses detailed errors so it never leaks database credentials, file paths, or stack traces to visitors. The tradeoff is that the actual reason for the failure is written somewhere you have to go looking for it.

On a Managed Cloud Shared Hosting account you do not have root, so you cannot read the global web server log or restart PHP. Everything you need, though, is reachable from your own account: the per-domain PHP error_log, the FOSSBilling application log, the debug flag inside the configuration file, and the PHP version and extension controls in cPanel or DirectAdmin. Working through those in order almost always turns a generic 500 into a specific, fixable message.

Turn on the real error message first

The single most useful move is to make FOSSBilling and PHP tell you what actually happened. FOSSBilling ships with a debug switch in its main config file. Open the File Manager in cPanel (Jupiter theme, Files → File Manager) or DirectAdmin (System Info & Files → File Manager), navigate to your document root (typically public_html), and edit config.php in the FOSSBilling root. Locate the debug value and set it temporarily:

'debug' => true,
'debug_and_monolog' => true,

With debug enabled, reload the page that was failing. Instead of a white screen you should now see the exception class, the message, and the file and line where it was thrown. Note that carefully, then set both values back to false the moment you finish diagnosing — leaving debug on in production exposes internal paths and is a security problem in its own right.

If the screen is still blank, PHP itself is dying before FOSSBilling can render anything, and the message goes to the PHP error log. Every domain writes to a local error_log file in the directory where the fault occurred. Check the FOSSBilling root and the public_html directory for a file literally named error_log, and open it in File Manager. The last few lines carry the fatal. You can also inspect FOSSBilling's own log at data/log/php_error.log and data/log/application.log, which capture Monolog output including database and dependency failures.

To guarantee PHP is logging at all, create or edit a .user.ini file in your document root and add:

display_errors = Off
log_errors = On
error_reporting = E_ALL
error_log = /home/USERNAME/public_html/data/log/php_error.log

Replace USERNAME with your account name and confirm the path exists. LiteSpeed honours .user.ini per directory, but it caches the file for a few minutes, so wait before assuming a change did not take effect.

Missing PHP extensions and wrong PHP version

A large share of FOSSBilling 500s on shared hosting trace back to the PHP version or a disabled extension. The application targets modern PHP (8.1 and above for current releases) and requires a specific set of modules: pdo_mysql, curl, openssl, mbstring, json, intl, xml/dom, zip, and gd or imagick. When one is absent you typically see a fatal like Uncaught Error: Call to undefined function or Class "IntlDateFormatter" not found in the logs.

Fix the version first. In cPanel open Software → Select PHP Version (MultiPHP Manager also lets you set the version per domain), and in DirectAdmin open Account Manager → PHP Selector under CloudLinux Selector. Set the domain to a supported release such as PHP 8.2. Do not jump to the newest bleeding-edge version without confirming FOSSBilling supports it, because a version that is too new can trigger deprecation fatals just as readily as one that is too old.

On the same screen, switch to the Extensions tab and tick the modules FOSSBilling needs. CloudLinux PHP Selector presents these as checkboxes; enable intl, curl, gd, mbstring, zip, openssl, and pdo_mysql if any are unchecked. Save, wait for the pool to recycle, and reload. If your account uses the ea-php stack under cPanel MultiPHP, the extensions appear in the PHP version selector's extension list rather than the CloudLinux tool — use whichever your account exposes.

After changing the version, clear the FOSSBilling compiled cache. A stale cache built against a different PHP version produces confusing fatals. Using File Manager, delete the contents of data/cache/ (the folder itself stays, only the files inside go). FOSSBilling regenerates them on the next request.

.htaccess rewrites, permissions, and the config file

When the homepage loads but /admin or any deep URL throws 500, suspect the rewrite rules. FOSSBilling relies on an .htaccess in the document root to route friendly URLs into index.php. If that file references an Apache directive LiteSpeed rejects, or contains a duplicated Options line, the whole request fails. A known-good baseline looks like this:

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule ^(.*)$ index.php [QSA,L]
</IfModule>

Avoid Options -Indexes +FollowSymLinks combinations if they trigger a 500; on many CloudLinux setups Options +FollowSymLinks is blocked and SymLinksIfOwnerMatch is required instead. If in doubt, temporarily rename .htaccess to .htaccess.bak and reload — if the 500 disappears, the file is the culprit and you can rebuild it from the snippet above.

File permissions are the other common trigger. FOSSBilling must write to data/ and its subfolders. On shared hosting, directories should be 755 and files 644; anything set to 777 can be refused by the suEXEC/suPHP layer and produce a 500. In File Manager, select the data folder, choose Permissions, set 755, and apply recursively. Also confirm config.php is present and syntactically valid — a stray character or an unclosed quote from a manual edit yields syntax error, unexpected... in the PHP log and a blank screen everywhere.

If the log points at a database connection failure rather than a PHP fatal, open phpMyAdmin from your control panel and confirm the database, user, and host in config.php match a real account. On shared hosting the host is almost always localhost, not a remote IP, and the database name carries your account prefix. A mismatch here surfaces as a 500 with a PDO exception once debug mode is on.

Work through these in sequence — debug flag, PHP log, extensions and version, then rewrites and permissions — and the vast majority of FOSSBilling 500s resolve without ever needing shell access. The pattern of enabling detailed logging, reading the exact exception, and correcting one variable at a time applies equally to background jobs; the same disciplined approach used for diagnosing silent cron failures works when a FOSSBilling scheduled task dies without visible output.