Cloudflare Tunnel: Not Working — Fix
The Problem
Your Cloudflare Tunnel is set up but services aren’t reachable. You might see: 502 Bad Gateway errors, the tunnel shows as “Inactive” in the Cloudflare dashboard, DNS records exist but the site won’t load, or connections hang and eventually time out.
The Cause
Cloudflare Tunnel issues typically stem from one of four areas: the cloudflared connector not running or failing to authenticate, incorrect ingress rules pointing to the wrong local address, DNS records not properly routing to the tunnel, or the local service not listening on the address cloudflared expects.
The Fix
Method 1: Check Tunnel Status
Verify the tunnel connector is running and connected:
# If running as a system service
sudo systemctl status cloudflared
sudo journalctl -u cloudflared -f
# If running in Docker
docker logs cloudflared
# Check tunnel status via API
cloudflared tunnel info <tunnel-name>
Look for:
Registered connectors— should show at least 1 active connectionERRlines — authentication failures, certificate issuesconnection reset by peer— network issue between your server and Cloudflare
Common fix: If the tunnel shows as “Inactive” in the dashboard but cloudflared is running, the tunnel token or credentials file may be expired. Regenerate:
# For token-based tunnels (recommended)
# Get a new token from Cloudflare dashboard: Zero Trust → Networks → Tunnels → Configure
docker restart cloudflared
# For credentials-file tunnels
cloudflared tunnel delete <tunnel-name>
cloudflared tunnel create <tunnel-name>
# Update the credentials-file path in config.yml
Method 2: Fix 502 Bad Gateway
A 502 error means cloudflared reached Cloudflare but can’t reach your local service.
Check: Is the service actually running on the address and port specified in your ingress rule?
# If your ingress says "service: http://localhost:8080"
curl -I http://localhost:8080
# If your ingress says "service: http://nextcloud:8080" (Docker)
docker exec cloudflared curl -I http://nextcloud:8080
Docker networking fix: If cloudflared runs in Docker and your services are also in Docker, they need to be on the same Docker network. Using localhost won’t work — use the container name:
services:
cloudflared:
image: cloudflare/cloudflared:2024.12.2
restart: unless-stopped
command: tunnel run
environment:
TUNNEL_TOKEN: ${CLOUDFLARE_TUNNEL_TOKEN}
networks:
- tunnel
nextcloud:
image: nextcloud:33.0.0
restart: unless-stopped
networks:
- tunnel
networks:
tunnel:
In the tunnel config, use http://nextcloud:80 not http://localhost:80.
Method 3: Fix DNS Routing
If the domain resolves but traffic doesn’t reach the tunnel:
- Check the DNS record in Cloudflare dashboard → DNS → Records
- The record should be a
CNAMEpointing to<tunnel-id>.cfargotunnel.comwith the orange cloud (proxied) enabled - If the record doesn’t exist, add it:
cloudflared tunnel route dns <tunnel-name> subdomain.yourdomain.com
Multiple subdomains: Each hostname in your ingress rules needs its own DNS CNAME record.
Method 4: Fix HTTPS/SSL Issues
If the service uses HTTPS internally (e.g., port 443 with a self-signed cert), cloudflared will fail to connect by default:
ingress:
- hostname: service.yourdomain.com
service: https://localhost:8443
originRequest:
noTLSVerify: true # Accept self-signed certs from your service
For services that require HTTP/2:
ingress:
- hostname: service.yourdomain.com
service: https://localhost:8443
originRequest:
http2Origin: true
Method 5: Fix WebSocket Services
Some apps (Home Assistant, Homarr, code-server) require WebSocket connections. cloudflared supports WebSockets by default, but you may need to ensure your service URL is correct:
ingress:
- hostname: ha.yourdomain.com
service: http://homeassistant:8123
If WebSocket connections drop, check your Cloudflare dashboard: SSL/TLS → Edge Certificates → ensure “Always Use HTTPS” isn’t causing redirect loops.
Prevention
- Pin your
cloudflaredversion — don’t use:latest. The tunnel protocol can change between versions. - Use token-based tunnels (Cloudflare dashboard-managed) instead of credentials-file tunnels — easier to rotate and manage.
- Monitor tunnel health from the Cloudflare Zero Trust dashboard — set up notifications for tunnel disconnections.
- Use a catch-all ingress rule at the bottom of your config to return a clear error instead of a generic 502:
ingress:
- hostname: app1.yourdomain.com
service: http://localhost:8080
- service: http_status:404 # Required catch-all
Related
Get self-hosting tips in your inbox
Get the Docker Compose configs, hardware picks, and setup shortcuts we don't put in articles. Weekly. No spam.
Comments