---
name: PHP app on Namecheap cPanel (PHP-FPM) 500s
description: Why a freshly-uploaded PHP app 500s on Namecheap/cPanel and how to diagnose domain-vs-Replit confusion.
---

# PHP app on Namecheap cPanel — HTTP 500 causes

When a user reports a deployed app returning HTTP 500, FIRST confirm *which server*
the domain points to. `getent hosts <domain>` — a `198.54.x.x` (or other Namecheap)
IP means the domain serves from **Namecheap cPanel**, NOT the Replit deployment.
The Replit deploy (model-network.replit.app here) can be perfectly healthy while the
custom domain 500s from a totally separate host. Check getDeploymentInfo() +
`additionalUrls` — if the custom domain isn't listed, it isn't wired to Replit.

**Top cPanel 500 cause for our generated PHP app:** `php_flag` / `php_value`
directives in `.htaccess`. Namecheap runs PHP as **PHP-FPM/CGI**, where those
directives are unknown to Apache and throw an immediate 500 ("Invalid command
'php_flag'"). Guard them with `<IfModule mod_php.c>` (and mod_php7/mod_php8) so they
only apply under classic mod_php; the real upload-exec protection is the
`<FilesMatch \.php$> Require all denied` block, which is FPM-safe. Per-PHP settings
on FPM go in `.user.ini`, not `.htaccess`.

**Other cPanel 500 triggers:** PHP version below the code's floor (our app needs 8.1+
for `never` return type — set it in MultiPHP Manager), missing/wrong `.env` DB creds,
bad file permissions. The real fatal is always in cPanel's `error_log`
(`~/public_html/error_log`).

# Unstyled site / CSS 404 on cPanel (BASE_URL)

"Pages load but unstyled" / "CSS 404" on the generated PHP app is almost always a
**base-path mismatch**, not a missing stylesheet (the design is one self-contained
`public/assets/css/style.css`; the app ships no JS). Asset links are built by a
`base_url()` helper = `BASE_URL . '/' . path`. If `BASE_URL` doesn't match the actual
URL path the app is served from, every `/assets/...` request 404s.

Fix shipped: `app/bootstrap.php` auto-detects `BASE_URL` from `$_SERVER['SCRIPT_NAME']`
when `.env` BASE_URL is empty — `dirname()`, strip a trailing `/public` (the root
`.htaccess` forwards traffic into `public/`, so SCRIPT_NAME includes it), normalize
`/`/`.` to ``. Handles all three cPanel layouts: doc root = project root
(SCRIPT_NAME=/public/index.php → ``), doc root = public/ (→ ``), subfolder install
(/sub/public/index.php → `/sub`). Explicit `.env` BASE_URL still overrides; normalize
an explicit `/` to `` to avoid `//asset` double slashes. Leave BASE_URL empty by default.
