cloudflare/cloudflared · error
tunnelCmdErrorMessage
tunnelCmdErrorMessage
Error message
You did not specify any valid additional argument to the cloudflared tunnel command. If you are trying to run a Quick Tunnel then you need to explicitly pass the --url flag. Eg. cloudflared tunnel --url localhost:8080/. Please note that Quick Tunnels are meant to be ephemeral and should only be used for testing purposes. For production usage, we recommend creating Named Tunnels. (https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/install-and-setup/tunnel-guide/)
What it means
TunnelCommand returns this error when the `cloudflared tunnel` subcommand receives no valid arguments (no hostname rule, no --url). Classic tunnel usage (setting `hostname` without `url`) is deprecated and also rejected first with errDeprecatedClassicTunnel. Quick Tunnels require an explicit --url flag; without it there is nothing for the command to do.
Source
Thrown at cmd/cloudflared/tunnel/cmd.go:270
// 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 {
// 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")
}View on GitHub (pinned to 2253eeeb25)
Solutions
- Pass --url, e.g. `cloudflared tunnel --url localhost:8080` for a Quick Tunnel (testing only).
- For production, create a Named Tunnel: `cloudflared tunnel create <name>`, add ingress rules to the config file, and run `cloudflared tunnel run <name>`.
- Remove the deprecated `hostname`-only classic tunnel configuration; classic tunnels are no longer supported.
Example fix
// before cloudflared tunnel // after cloudflared tunnel --url localhost:8080
Defensive patterns
Strategy: validation
Validate before calling
if [ $# -eq 0 ]; then echo "usage: cloudflared tunnel --url <addr> | cloudflared tunnel run <name>" >&2; exit 1; fi
Prevention
- Always pass --url for Quick Tunnels in scripts and docs.
- Use `cloudflared tunnel run <name>` for Named Tunnels instead of bare `tunnel`.
- Migrate legacy hostname-based classic tunnel configs to ingress rules.
When it happens
Trigger: Running `cloudflared tunnel` with no --url and no ingress hostname; or setting `hostname` which triggers the deprecated classic-tunnel check before this error.
Common situations: Users following old classic-tunnel tutorials; users expecting Quick Tunnel to start without --url; shell scripts that dropped the --url argument.
Understand the failure class
Background: "--flag is required" and "must specify" CLI errors: how missing-required-flag validation works and how to fix it — this error's family across 20 libraries.
Related errors
- ErrNoTunnelID
- ErrInvalidTunnelID
- errDeprecatedClassicTunnel
- --metrics has to be provided
- Did not receive final destination from client. The --destina
AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06).
Data as JSON: /api/errors/f84f9870dfa6c1c2.
Report an issue: GitHub.