Production Operations on a Single Server · 9/10

Troubleshoot 502, 504, and HTTPS Errors Layer by Layer

What will this help you do?

Trace faults through DNS, network access, TLS, Caddy, the local upstream, application, and database using evidence at each layer instead of blindly restarting the server.

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.

Updated

On this page

Record the symptoms before restarting anything

A restart sometimes restores service, but it can erase the most useful short-lived evidence and leave the cause unknown. First record the time, domain, status code, whether every page is affected, the most recent release, and what happens from another network. Save response headers and relevant logs before changing the system.

A 502 usually means a proxy did not receive a usable response from its upstream. A 504 more often means the upstream did not finish in time. A TLS error occurs before the request reaches the HTTP application. They can be related, but investigate from the outside inward.

Layer 1: confirm DNS reaches the intended server

bash
dig +short A www.example.com
dig +short AAAA www.example.com

Compare the results with the current server. An old or incorrect AAAA record can send some visitors to a broken IPv6 destination. Test from different networks to distinguish a local DNS cache from authoritative records. After a recent DNS change, check the TTL instead of repeatedly reversing the record.

Layer 2: check ports 80/443 and TLS

Use curl -Iv https://www.example.com to inspect the connection, certificate host name, expiry, and handshake errors. Confirm that cloud firewall rules and UFW allow the necessary traffic and Caddy is listening on 80/443. If certificate issuance failed, read the specific challenge error in Caddy logs and check that DNS reaches this server and another process has not taken the ports.

Do not ask visitors to click through an untrusted-certificate warning. Check system time, certificate chain, host-name match, and whether a CDN sits in front of the proxy. The HTTPS troubleshooting guide covers the fundamentals in more detail.

Layer 3: check where Caddy sends the request

bash
sudo caddy validate --config /etc/caddy/Caddyfile
systemctl status caddy --no-pager
journalctl -u caddy --since '20 minutes ago' --no-pager

Inspect the domain's site block, path matching, and reverse_proxy target. In a container setup, 127.0.0.1 means something different depending on whether Caddy runs on the host or inside a container. Targeting the wrong network namespace is a common cause of 502. If the configuration changed recently, compare it with the backup instead of stacking more speculative edits.

Layer 4: request the upstream directly

bash
curl -v --max-time 10 http://127.0.0.1:3000/health
ss -lntp | grep ':3000'
systemctl status myapp --no-pager

If the local request fails, focus on the application or a deeper dependency. If it succeeds while the public route returns 502, focus on the proxy target, protocol, host header, path, and network. If nothing listens on the port, read the service start logs. Changing the public firewall will not fix a failed loopback request.

Layer 5: decide whether the app crashed, stalled, or waited on something

Look at logs around the incident, restart counts, CPU, memory, disk, and out-of-memory records. A process that exits immediately often has a configuration, permission, or port-conflict problem. A running process whose requests time out may be blocked by the event loop, a full connection pool, disk I/O, or a downstream API.

Do not begin a 504 investigation by simply increasing the proxy timeout. If an operation should take one second, allowing it a minute may only make users wait longer and tie up more connections. Find where time is spent, then decide whether to optimize, move the work to an asynchronous job, or adjust a justified timeout.

Layer 6: inspect the database and disk without risking data

Check database connectivity, connection counts, locks, slow queries, and free disk space. A full disk or unwritable SQLite directory can let reads succeed while writes fail. An exhausted PostgreSQL pool can make new requests queue. Protect data first; do not delete lock or database files blindly.

Verify all layers after the fix

Recheck public HTTPS, the proxy, local health, and a key user action. Confirm that monitoring has recovered. Record the cause, trigger, evidence, fix, and prevention step. If a restart brought the site back but the cause remains unknown, the incident is not fully resolved.

The next guide turns deployment, monitoring, and troubleshooting into a routine: the server maintenance and incident runbook.

Sources

  1. Caddy reverse_proxy directiveCaddy Documentation
  2. journalctlsystemd

Next steps

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

  1. Deploy Open WebUI with Docker and Persistent Storage →
  2. Install Ollama on Linux and Expose It Safely →
  3. Deploy Dify with Docker Compose: A Production-minded Guide →
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