cloudflare/cloudflared · error
use `cloudflared tunnel run` to start tunnel %s
Error message
use `cloudflared tunnel run` to start tunnel %s
What it means
cloudflared refuses to start a tunnel when the configuration file already contains a tunnel ID, because providing a TunnelID means `tunnel run` semantics were intended, not `tunnel` (proxy-dns style) invocation. The library throws this to catch users who configured a tunnel but invoked the wrong subcommand. It is a guard against running named tunnels without the proper `run` command flow.
Source
Thrown at cmd/cloudflared/tunnel/cmd.go:262
}
tunnelURL := c.String("url")
if tunnelURL == hostname && tunnelURL != "" && hostname != "" {
return fmt.Errorf("hostname and url shouldn't match. See --help for more information")
}
return runAdhocNamedTunnel(sc, name, c.String(CredFileFlag))
}
// Run a quick tunnel
// A unauthenticated named tunnel hosted on <random>.<quick-tunnels-service>.com
shouldRunQuickTunnel := c.IsSet("url") || c.IsSet(ingress.HelloWorldFlag)
if c.String("quick-service") != "" && shouldRunQuickTunnel {
return RunQuickTunnel(sc)
}
// If user provides a config, check to see if they meant to use `tunnel run` instead
if ref := config.GetConfiguration().TunnelID; ref != "" {
return fmt.Errorf("use `cloudflared tunnel run` to start tunnel %s", ref)
}
// Classic tunnel usage is no longer supported
if c.String("hostname") != "" {
return errDeprecatedClassicTunnel
}
return errors.New(tunnelCmdErrorMessage)
}
func Init(info *cliutil.BuildInfo, gracefulShutdown chan struct{}) {
buildInfo, graceShutdownC = info, gracefulShutdown
}
// runAdhocNamedTunnel create, route and run a named tunnel in one command
func runAdhocNamedTunnel(sc *subcommandContext, name, credentialsOutputPath string) error {
tunnel, ok, err := sc.tunnelActive(name)
if err != nil || !ok {View on GitHub (pinned to 2253eeeb25)
Solutions
- Change the command to `cloudflared tunnel run` (optionally with `--token` or credentials flags).
- If you really intend non-run behavior, remove the `tunnel:` (TunnelID) entry from the config file or unset it via `TUNNEL_ID` env override.
- If embedding cloudflared, invoke the `tunnel run` action instead of the bare TunnelCommand when configuration contains a tunnel ID.
Example fix
// before ExecStart=/usr/local/bin/cloudflared tunnel --config /etc/cloudflared/config.yml // after ExecStart=/usr/local/bin/cloudflared tunnel --config /etc/cloudflared/config.yml run
Defensive patterns
Strategy: validation
Validate before calling
// shell: fail fast if config declares a tunnel ID if grep -qE '^tunnel:' /etc/cloudflared/config.yml; then exec cloudflared tunnel --config /etc/cloudflared/config.yml run fi exec cloudflared tunnel --config /etc/cloudflared/config.yml
Prevention
- Always use `tunnel run` once a tunnel ID or token exists in config.
- Keep positional-argument style (`cloudflared tunnel <ID>`) out of scripts and units.
- Validate deployment templates against the current cloudflared command surface after upgrades.
When it happens
Trigger: Running `cloudflared tunnel` (or an embedded TunnelCommand via the CLI app) when the resolved config file has `tunnel: <ID>` set, instead of running `cloudflared tunnel run`. Also triggered by script wrappers that call TunnelCommand directly with a config containing TunnelID.
Common situations: Users follow an old tutorial that says `cloudflared tunnel <UUID>` as a positional argument style; or a systemd unit / Docker entrypoint invokes `cloudflared tunnel` with a config file that lists tunnel ID. Also common after moving credentials into config but forgetting to change the command to `run`.
Understand the failure class
Background: "mutually exclusive" flag errors: what "can't supply both nx and xx", "--raw is not compatible with -i" and "cannot be used with" mean, and how to fix them — this error's family across 29 libraries.
Related errors
- configuration file %s must contain entries for the tunnel to
- ErrNoTunnelID
- ErrInvalidTunnelID
- errDeprecatedClassicTunnel
- tunnelCmdErrorMessage
AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06).
Data as JSON: /api/errors/d29933d19dcf2875.
Report an issue: GitHub.