Fix Caddy Reverse Proxy 404 and 502 Errors: Upstream, Path, and Body Limits

What will this help you do?

A step-by-step guide to diagnosing and fixing 404 and 502 errors in Caddy reverse proxy setups by checking logs, upstream addresses, path stripping, and request body limits.

Who is it for?

Readers working through this problem and checking each step.

Before you start

Check the scope of this guide, then prepare the environment and materials it actually calls for.

On this page

Preparation: Verify Environment and Log Access

Before troubleshooting, ensure you have SSH access to the server and can view Caddy logs. Caddy logs are essential for distinguishing between routing errors (404) and upstream failures (502). Use the caddy command or your system's log manager to access recent entries. Confirm that Caddy is running and that your Caddyfile is valid by checking for startup errors. If you cannot access logs, you cannot accurately diagnose whether the issue lies in Caddy's routing logic or the backend service's availability.

Step 1: Distinguish 404 vs 502 via Caddy Logs

Open the Caddy logs and search for the specific error codes. A 502 Bad Gateway typically indicates that Caddy could not connect to the upstream server or received an invalid response. A 404 Not Found usually means the request path did not match any defined handler or the file server could not locate the resource. Look for log entries that mention "upstream" for 502 errors or "no match" or "file not found" for 404 errors. This initial classification prevents you from wasting time on the wrong configuration section. If the logs show connection refused, the issue is likely the upstream service. If they show a path mismatch, focus on your routing directives.

Step 2: Troubleshoot 502 Errors: Upstream Status and Address

For 502 errors, verify that the upstream service is running and listening on the correct address and port. Use ss -tlnp or netstat -tlnp on the server to check which ports are active. Compare this output with the reverse_proxy directive in your Caddyfile. For example, if your Caddyfile specifies reverse_proxy localhost:8080, ensure your application is actually listening on port 8080. If the application is bound to 127.0.0.1 but Caddy is trying to connect via a different interface, or if the port is off by one, you will get a 502. Restart the upstream service if it appears to be hung. Also, check if the upstream is returning a valid HTTP response; some applications may crash on specific requests, causing intermittent 502s.

Step 3: Troubleshoot 404 Errors: handle_path and Prefix Stripping

If you are proxying a sub-path (e.g., /api), ensure that the path prefix is correctly handled. The handle_path directive implicitly strips the matched path prefix from the request URI before passing it to the next handler. For instance, if you use handle_path /api/*, a request to /api/users will be forwarded to the upstream as /users. If your upstream application expects the full path /api/users, you should use handle instead of handle_path, or adjust your application's routing. If you are using handle_path but your app returns 404, it is likely because the app does not recognize the stripped path. Test this by checking the upstream logs to see what path it received.

Step 4: Check File Server and Root Directory Configuration

For static files, ensure the file_server directive is paired with the correct root directive. The file_server appends the request's URI path to the site's root path. If your root is set to /var/www/html and you request /images/logo.png, Caddy will look for /var/www/html/images/logo.png. If the file does not exist at that exact location, you will get a 404. Verify the file permissions and ownership. Also, note that file_server enforces canonical URIs; requests to directories without a trailing slash will be redirected. If you are seeing 404s for static assets, double-check the root path and the actual file location on the disk.

Step 5: Check Request Body Limits for Large Uploads

If your 404 or 502 errors occur specifically during file uploads, check the request_body directive. By default, Caddy may limit the size of request bodies. If you are uploading large files, you may need to increase the max_size limit. For example, request_body { max_size 100MB } allows uploads up to 100 megabytes. If the request body exceeds this limit, Caddy will return a 413 Payload Too Large error, which might be misinterpreted or cause upstream timeouts leading to 502s. Note that the set subdirective for request_body is experimental in v2.10.0+. Ensure your Caddy version supports the directives you are using. If you are not uploading large files, this step is not necessary.

Verification and Rollback: Test Access and Hot Reload

After making changes to your Caddyfile, apply them using caddy reload to avoid downtime. Then, test the specific URL that was failing using curl -I in your terminal. Check the HTTP status code in the response headers. If it returns 200 OK, the issue is resolved. Monitor the Caddy logs for a few minutes to ensure no new errors appear. If the problem persists, revert your changes to the previous known good configuration. Keep a backup of your Caddyfile before making significant changes. This allows you to quickly roll back if a fix introduces new issues. Always test in a staging environment if possible before applying changes to production.

Verifying Upstream and Transport Options

When diagnosing persistent 502 or 404 errors, reviewing transport behaviors and upstream configurations defined in the official Caddyfile reverse_proxy documentation ensures that load balancing, active health checks, and header rewrites operate correctly. For deeper multi-tier architectures, you can also consult Design a Single-Server Setup: Reverse Proxy, App, and Database / 单服务器生产架构怎么画:反向代理、应用、数据库与端口边界 to map out strict port boundaries, or check Troubleshoot 502, 504, and HTTPS Errors Layer by Layer / 502、504 与 HTTPS 故障怎么查:从 DNS 到应用的分层排错 for comprehensive layer-by-layer diagnostics.

Sources

Next steps

Continue with the next useful task; you do not need to read everything at once.

  1. How Caddy Automatic HTTPS Works and How to Troubleshoot It →
  2. Deploy Your First Static Website to a Linux Server with Caddy →
  3. First Hour on a New Ubuntu or Debian Server →
RESOURCES I USE · REFERRAL

Two services to compare when you are ready to launch

This is not an automated ranking, and neither service is necessary for everyone. These are services I use, with the use case and limitations kept visible.

Cloud server · Used for early projects

RainYun

A practical candidate for a website or small service. Choose by user region, configuration and measured workload rather than the lowest headline price.

Referral disclosure: these links contain my referral information. I may receive a platform benefit if you sign up or order, at no additional charge from AIOOS. Check the order page for current pricing, availability, regions and terms. Read the full affiliate disclosure