I'm encountering a consistent "Application not found" error when trying to access an internal application I've exposed via a Cloudflare Tunnel. The application is a simple metrics dashboard (Grafana) running in a Docker container on a private VM. The tunnel itself is established and healthy according to `cloudflared` logs, and I can reach the application directly via localhost on the VM. However, when I attempt to access the configured application hostname through the Access portal, it fails with this error.
My setup uses a self-hosted `cloudflared` daemon, and I've followed the standard integration workflow: creating the tunnel, routing traffic to the local service, and then building an Access policy for it. The Access policy is configured with my email domain, and the application appears in the Zero Trust dashboard with a green "Healthy" status for the tunnel connection. This discrepancy between the dashboard status and the actual user-facing error is particularly puzzling.
Here is the relevant portion of my `cloudflared` configuration YAML:
```yaml
tunnel: metrics-tunnel-01
credentials-file: /etc/cloudflared/metrics-tunnel-01.json
ingress:
- hostname: grafana.internal.mycompany.com
service: http://localhost:3000
originRequest:
noTLSVerify: true
- service: http_status:404
```
And the Access application is configured with the same hostname: `grafana.internal.mycompany.com`. The DNS record for this hostname is a CNAME to the tunnel's canonical URL, which I've verified is correct.
I have already methodically checked the following:
* Tunnel status: `cloudflared tunnel list` shows the tunnel as active.
* Routing: `cloudflared tunnel route ip show` confirms the route is present.
* Local service: `curl http://localhost:3000` from the VM returns the Grafana login page successfully.
* Access policy: The policy uses an "Include" rule for my email domain and is set to "Allow" with no additional rules or requirements.
The error suggests Access is not correctly associating my request with the defined application, despite the hostname match. Has anyone encountered this with a self-hosted tunnel setup? I am specifically interested in any potential configuration conflicts, such as:
1. A mismatch in the hostname evaluation order between the tunnel's ingress rules and the Access application definition.
2. A known issue where the `originRequest` configuration, particularly `noTLSVerify`, might interfere with Access handshakes.
3. A required sequence or delay between establishing the tunnel route and enabling the Access application that I may have missed.
Any insights into the diagnostic steps beyond the dashboard's "Healthy" status would be greatly appreciated. I am looking to establish a reliable, auditable access pattern for internal tools, and this blockage is preventing me from benchmarking the latency and reliability of this pattern versus a traditional VPN.
--DC
data is the product
The error typically occurs at the routing layer, before your Access policy is even evaluated. Your ingress rule shows `hostname: grafana.internal.mycom`. Is this the exact domain you're using in the Access application configuration? Even a minor mismatch (like a missing subdomain) will cause this.
Check your tunnel's routing configuration in the Zero Trust dashboard under Network > Tunnels. Verify the public hostname for that tunnel is the same as your Access app domain. A common slip is having the tunnel route to `grafana.internal.mycom` but the Access app configured for `grafana.mycom`.
Also, run `cloudflared tunnel route dns metrics-tunnel-01` to confirm the DNS record exists and is correct. The "Healthy" status just means the daemon is connected, not that the routing is properly resolved to your application.
BenchMark
That's the obvious first check, but the dashboard's tunnel status can be misleading in a couple ways. It says "Healthy" if the daemon's heartbeat is fine, even if the actual routing config is a mess. I've seen it show green while the underlying CNAME was still propagating or pointed at a ghost record from a deleted tunnel.
More to the point, if the Access policy was built after the tunnel route, sometimes the Access app ends up with a slightly different internal service validation. Have you tried hitting the tunnel's public hostname directly, bypassing Access entirely, to see if the routing alone works? That isolates the problem.
cg