Problem: HTTPS Upstream Connection Refused
Symptoms
- A route for Proxmox (port 8006), PBS (port 8007), or another HTTPS-only service returns 502 or the holding page
- Logs show
connection refusedortls: first record does not look like a TLS handshake - The service works fine when accessed directly (e.g.,
https://proxmox.lan:8006) - The route upstream is set to
proxmox.lan:8006without a scheme
Why this happens
Caddy defaults to dialing upstreams over plain HTTP. If the upstream is HTTPS-only (like Proxmox, Proxmox Backup Server, or any service that redirects HTTP to HTTPS on the same port or flat-out rejects non-TLS), the connection fails because Caddy sends an HTTP request to a port that expects a TLS handshake.
ProxyOS has auto-detection for a set of well-known HTTPS ports:
443, 8006, 8007, 8443, 9090, 9443, 10443
If your upstream address uses one of these ports without an http:// prefix, ProxyOS auto-detects it as HTTPS and enables the TLS transport block in Caddy, including insecure_skip_verify: true (because self-signed certs are the norm on services like Proxmox).
The problem occurs when:
- You prefix the upstream with
http://explicitly, overriding auto-detection - The HTTPS service is on a non-standard port not in the auto-detection list
Diagnosis
Test what happens without ProxyOS:
# This should fail (wrong scheme)
curl http://proxmox.lan:8006
# This should work
curl -k https://proxmox.lan:8006
Check the route's upstream address in the dashboard:
Look at the upstream field. Does it have http:// as a prefix? If so, change it to https:// or remove the scheme prefix entirely (and let auto-detection kick in for known ports).
Check container logs:
docker compose logs proxyos | grep "tls\|handshake\|proxmox"
Look for tls: first record does not look like a TLS handshake — this is the definitive sign that Caddy is dialing HTTP to an HTTPS port.
Fix
Fix 1: Use the https:// prefix in the upstream address
Edit the route and change the upstream from:
proxmox.lan:8006
to:
https://proxmox.lan:8006
ProxyOS will set insecure_skip_verify: true automatically when the https:// prefix is present (because Proxmox and PBS use self-signed certificates).
Fix 2: Remove the http:// prefix
If you have http://proxmox.lan:8006, change it to proxmox.lan:8006 (no scheme). Port 8006 is in the auto-detection list so ProxyOS will detect it as HTTPS and handle it correctly.
Fix 3: Enable Skip TLS Verify for custom HTTPS ports
If your HTTPS service is on a port not in the auto-detection list:
- Use
https://your-service:custom-portas the upstream - Enable Skip TLS Verify on the route if the upstream uses a self-signed certificate
Prevention
- Always test upstream connectivity from inside the container before saving the route
- For Proxmox, PBS, and similar services, use
https://host:portas the upstream address