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

  1. Pass --url, e.g. `cloudflared tunnel --url localhost:8080` for a Quick Tunnel (testing only).
  2. For production, create a Named Tunnel: `cloudflared tunnel create <name>`, add ingress rules to the config file, and run `cloudflared tunnel run <name>`.
  3. 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

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


AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06). Data as JSON: /api/errors/f84f9870dfa6c1c2. Report an issue: GitHub.