Start by identifying which connection failed
Cloudflare Tunnel adds a specific hop: browser → Cloudflare edge → cloudflared connector → application origin. A working connector does not imply the application is listening. Record the precise HTTP status, response headers, hostname, path and time before changing settings.
For a Cloudflare Tunnel route, a 502 with an origin-unreachable message commonly means cloudflared is connected to Cloudflare but cannot reach the configured local service. Error 522 describes a timeout reaching an origin in Cloudflare's proxied origin connection model. Error 525 describes a failed TLS handshake between Cloudflare and an origin when Full or Full (strict) encryption is in use. Avoid assuming all three have the same resolution.
Verify the local application before touching DNS
On a dedicated JoeC VM with the connector on the same host, begin at the application. The intended Apache origin is HTTP on loopback port 8080. Run a local test from that same VM:
sudo systemctl status apache2 --no-pager
sudo ss -lntp | grep ':8080'
curl -i -H 'Host: joec.pw' http://127.0.0.1:8080/healthz.txt
sudo journalctl -u cloudflared --since '-30 minutes' --no-pager
A healthy GET to healthz.txt returns HTTP 200 and the text ok. If curl fails with connection refused, first verify Apache is running and has a listener at the expected port. If the origin works from the host but the public hostname fails, check the Cloudflare Tunnel route's Service URL and connector logs. An origin configured as 127.0.0.1 on a *different* VM points at the wrong machine.
Separate gateway, timeout and TLS symptoms
- Tunnel 502: inspect cloudflared logs, service URL scheme, port, container networking and the origin listener. HTTPS configured against an HTTP-only service can produce confusing failures.
- Cloudflare 522: consider origin address, firewall rules, routing, overload and dropped packets for conventional proxied origins. A tunnel deployment has a different routing model, so first confirm the failing request actually uses the tunnel.
- Cloudflare 525: inspect origin TLS certificate, SNI configuration, allowed TLS versions/ciphers and service endpoint. The JoeC loopback HTTP leg does not itself require a TLS certificate; do not add HTTPS internally without designing that termination point.
Capture Cloudflare-generated error headers such as cf-error-type when present; origin-generated errors may not have them. Do not publish your tunnel token or full diagnostic logs.
Confirm recovery and prevent recurrence
Retest the internal health endpoint, then the public URL from a separate client. Verify an actual HTML page and, if present, a PHP endpoint rather than relying on a static health file alone. Compare response status and timing to the incident start; leave firewall rules restrictive. Add service monitoring for Apache, cloudflared and the external hostname so an origin-only success cannot mask a public outage.