Skip to content

Resource exhaustion due to missing static assets proxying to frankenphp-worker #1114

@eugene-nuwber

Description

@eugene-nuwber

Octane Version

2.9

Laravel Version

12

PHP Version

8.4

What server type are you using?

FrankenPHP

Server Version

1.12

Database Driver & Version

No response

Description

The current Caddy configuration template for FrankenPHP utilizes a broad try_files directive:
try_files {path} frankenphp-worker.php

This logic causes all requests for non-existent static files (e.g., versioned assets like app-v123.js after a deployment) to be forwarded to the PHP worker. In high-traffic environments, a surge of requests for missing assets triggers unnecessary PHP process execution, leading to worker saturation, increased CPU/Memory overhead, and potential system failure.

Technical Impact

  • Performance: High overhead for 404 responses that should be handled at the web-server level.
  • Stability: Potential DoS condition when static asset paths are brute-forced or when client-side caches request deprecated versioned files.
  • Resource Allocation: PHP workers are occupied by I/O-bound requests for missing files instead of processing dynamic application logic.

Proposed Solution
Refactor the Caddyfile logic to isolate static file handling. A dedicated matcher for common file extensions should be implemented to ensure that if a static file is not found on disk, Caddy returns a 404 Not Found immediately, bypassing the php_server or php_dispatch logic.

Recommended Configuration Change
Define a matcher for static assets and handle them via file_server exclusively:

@static {
    path *.css *.js *.mjs *.map *.ico *.png *.jpg *.jpeg *.gif *.svg *.webp *.avif *.woff *.woff2 *.ttf *.otf *.eot *.mp4 *.webm *.ogg *.mp3 *.wav *.pdf *.zip *.txt *.xml *.json *.wasm *.webmanifest *.manifest
}

file_server @static

Steps To Reproduce

  1. Deploy Laravel Octane with FrankenPHP.
  2. Request a non-existent file with a .js or .css extension.
  3. Observe that the request is processed by frankenphp-worker.php (returning a Laravel 404) instead of a native Caddy 404.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions