cloudflare/cloudflared · error
error running tunnel
Error message
error running tunnel
What it means
After creating or reusing the tunnel and applying any --route, runAdhocNamedTunnel starts the tunnel with sc.run(tunnel.ID); any failure there (connecting to Cloudflare edge, serving the origin, credential/protocol problems) is wrapped as 'error running tunnel'. It signals the tunnel process exited with an error rather than being a creation-time problem.
Source
Thrown at cmd/cloudflared/tunnel/cmd.go:299
// pass empty string as secret to generate one
tunnel, err = sc.create(name, credentialsOutputPath, "")
if err != nil {
return errors.Wrap(err, "failed to create tunnel")
}
} else {
sc.log.Info().Str(LogFieldTunnelID, tunnel.ID.String()).Msg("Reusing existing tunnel with this name")
}
if r, ok := routeFromFlag(sc.c); ok {
if res, err := sc.route(tunnel.ID, r); err != nil {
sc.log.Err(err).Str("route", r.String()).Msg(routeFailMsg)
} else {
sc.log.Info().Msg(res.SuccessSummary())
}
}
if err := sc.run(tunnel.ID); err != nil {
return errors.Wrap(err, "error running tunnel")
}
return nil
}
func routeFromFlag(c *cli.Context) (route cfapi.HostnameRoute, ok bool) {
if hostname := c.String("hostname"); hostname != "" {
if lbPool := c.String(cfdflags.LBPool); lbPool != "" {
return cfapi.NewLBRoute(hostname, lbPool), true
}
return cfapi.NewDNSRoute(hostname, c.Bool(overwriteDNSFlagName)), true
}
return nil, false
}
func StartServer(
c *cli.Context,
info *cliutil.BuildInfo,View on GitHub (pinned to 2253eeeb25)
Solutions
- Read the wrapped inner error — it names the actual failing stage (edge connection, credentials, origin).
- Try --protocol http2 if QUIC/UDP is blocked by the network.
- Re-run `cloudflared tunnel login` or re-create the tunnel if the credentials file is missing/corrupt.
- Verify the origin service URL in your config is reachable (`curl` it locally).
- Ensure outbound TCP 443 (and UDP 7844 for QUIC) to Cloudflare edge is allowed.
Example fix
// before cloudflared tunnel run --name mytunnel # QUIC blocked by firewall // after cloudflared tunnel run --name mytunnel --protocol http2
Defensive patterns
Strategy: retry
Validate before calling
# preflight nc -z -w3 region1.v2.argotunnel.com 443 || echo "edge TCP 443 blocked" # and ensure the credentials file exists: test -f ~/.cloudflared/<TUNNEL-ID>.json || echo "credentials missing"
Try / catch
for attempt := 0; attempt < 3; attempt++ {
err := runTunnelCmd()
if err == nil { break }
if strings.Contains(err.Error(), "error running tunnel") && isTransient(err) {
time.Sleep(backoff(attempt)); continue
}
log.Fatal(err)
} Prevention
- Allow egress on TCP 443 and UDP 7844 to Cloudflare edge; fall back to --protocol http2 when UDP is blocked
- Keep the tunnel credentials JSON alongside cert.pem and don't move it
- Verify origin services are listening before starting the tunnel
- Supervise the process (launchd/systemd) with restart policies for transient edge drops
When it happens
Trigger: `cloudflared tunnel run --name <name>` where sc.run(tunnel.ID) returns an error: cannot reach Cloudflare edge (network/firewall blocking QUIC 7844/UDP or HTTPS 443), invalid or unreadable credentials file, hostname not routed, origin unreachable causing serve failure, or context canceled with an error exit.
Common situations: Corporate firewalls blocking UDP/QUIC (fix: --protocol http2); credentials file moved or deleted; ICMP/egress restrictions; bad local origin URL in config so the proxy fails immediately; running in an environment without outbound 443.
Related errors
- failed to create tunnel
- ErrTunnelNameConflict
- tunnel name required
- you cannot use UUIDs as tunnel names
- ErrNoTunnelID
AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06).
Data as JSON: /api/errors/744862760fc583d7.
Report an issue: GitHub.