Caddy 2.11.9: Patch the PHP Gateway and Verify Its Routes
Upgrade Caddy’s PHP gateway, confirm the patched process is serving traffic, and verify public, directory-index and protected routes before closing the rollout.
DM
Imagine you’ve just updated Caddy on a small PHP site. The homepage loads, but the admin directory returns a 404. Your uptime check stays green because it never visits that part of the site. That’s the kind of gap worth closing when you roll out Caddy 2.11.9.
If you run Caddy 2.11.8 in front of PHP, follow the maintainers’ 5 November 2026 release guidance and upgrade to a fixed build. Verify the process that actually serves traffic, then check a public PHP page, a directory index and a protected route. A healthy homepage covers only one of those checks.
What changed between the two releases
Caddy’s php_fastcgi directive is a shortcut for routing requests to a FastCGI responder such as PHP-FPM. Its default logic can rewrite a request before handing it over. That means the PHP script a visitor needs isn’t always named in the URL. A request for /wp-admin/, for example, needs the directory’s PHP index to be selected.
The 2.11.9 release notes describe a 2.11.8 regression where a directory could be selected instead of its index script. The request could fail without ever reaching PHP. That is why an admin 404 after this specific update can point to routing rather than a broken WordPress installation. Other faults can produce a 404 too; use the running version, matching route and logs to narrow it down.
The releases also address separate security problems. Caddy’s 4 November path-authorization advisory lists versions 2.4.6 through 2.11.7 as affected by that specific issue and 2.11.8 as its patch. The next release adds fixes of its own, including one that makes configured FastCGI HTTP_* variables take precedence over matching client headers. If a PHP application consumes a gateway-provided identity, check that trust boundary during the rollout. These are Caddy fixes; updating PHP-FPM alone does not replace the gateway.
Identify the running gateway before you update
Trace one hostname from its public endpoint to the Caddy instance and the PHP-FPM upstream. Record how that instance was installed: distribution package, container image or custom binary. Include every replica that can accept traffic. An updated CLI on your shell’s path tells you nothing about a different container still handling requests.
For a conventional Caddyfile-based Linux service, these are useful inspection commands. Adjust the unit name, binary and config path to match your deployment. The Caddy CLI reference describes validation, and the service documentation explains the standard unit and its overrides.
systemctl show caddy.service -p MainPID -p ExecStart
caddy version
caddy validate --config /etc/caddy/Caddyfile --adapter caddyfileThe first command identifies the service’s main process and start command. caddy version reports the binary you invoked. Compare those observations before calling the service patched. On Linux, an authorized operator can use /proc/<PID>/exe to identify the executable backing the live process. For a container deployment, check the running container’s image identity and Caddy version after replacement. A changed image tag in a repository does not show that the new image is running.
Roll out the fix using the installation you already own
Use the supported installation channel for your setup. Check the fixed version or vendor backport you will actually deploy. If the build includes extra modules, carry them into the replacement and validate the real config with that build and its required environment. Keep a copy of the deployed configuration and a recovery plan that preserves access controls.
Stage the update before widening traffic when your setup allows it. Replace the running process or container as your deployment requires, then check its version and startup logs. Reloading a Caddyfile changes configuration in the running process; it does not by itself swap the executable. Don’t work around a failing route by opening the PHP-FPM listener or removing authentication.
Give public and protected routes separate checks
- Static control: open a known asset and confirm the response is the expected file. This checks the public path to the gateway without proving PHP executed.
- Dynamic control: open a known public PHP-backed page and verify a distinctive part of the application response. Use an endpoint where a cached response won’t mask the result.
- Directory index: request the real trailing-slash URL, such as /wp-admin/ on a WordPress site. Confirm its expected login redirect or authenticated page. A 200 at the end of a redirect chain can hide an unexpected first response.
- Protected route: with a fresh unauthenticated session or a low-privilege test account, confirm the expected denial or login flow and no protected content. With a permitted test account, check that the intended page still works. If you configure an identity in FastCGI, verify the application sees the intended server-side identity in a private test environment.
For the hypothetical site, record the version and instance alongside each route’s first response, final page and relevant log timestamp. If the static control works but only the directory index fails, examine the route and PHP handoff before changing the application. If a protected route unexpectedly succeeds, pause rollout and isolate the affected path through your existing controls. A few successful requests give useful rollout evidence; they don’t prove every security case or rule out prior exposure.
If you’re also changing the WordPress stack, Krova’s local-to-staging testing guide explains why a local plugin test can’t replace verification through the web server that will actually serve the site.
Verify the gateway on a separate Linux stack
A self-managed Cube gives you control of the Caddy build, PHP-FPM and route configuration for a rehearsal. Use test accounts and keep the environment private. Updating and validating the software you install remains your responsibility.
Creation context: This AI-assisted guide uses a hypothetical site and documented commands. No Caddy deployment, exploit reproduction or route test was performed for this article. The cover is a generated illustration.




