{"record":{"id":"0fae24c14583daf3","repo":"cloudflare/cloudflared","slug":"failed-to-create-tunnel","errorCode":null,"errorMessage":"failed to create tunnel","messagePattern":"failed to create tunnel","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/cloudflared/tunnel/cmd.go","lineNumber":284,"sourceCode":"\tif c.String(\"hostname\") != \"\" {\n\t\treturn errDeprecatedClassicTunnel\n\t}\n\n\treturn errors.New(tunnelCmdErrorMessage)\n}\n\nfunc Init(info *cliutil.BuildInfo, gracefulShutdown chan struct{}) {\n\tbuildInfo, graceShutdownC = info, gracefulShutdown\n}\n\n// runAdhocNamedTunnel create, route and run a named tunnel in one command\nfunc runAdhocNamedTunnel(sc *subcommandContext, name, credentialsOutputPath string) error {\n\ttunnel, ok, err := sc.tunnelActive(name)\n\tif err != nil || !ok {\n\t\t// pass empty string as secret to generate one\n\t\ttunnel, err = sc.create(name, credentialsOutputPath, \"\")\n\t\tif err != nil {\n\t\t\treturn errors.Wrap(err, \"failed to create tunnel\")\n\t\t}\n\t} else {\n\t\tsc.log.Info().Str(LogFieldTunnelID, tunnel.ID.String()).Msg(\"Reusing existing tunnel with this name\")\n\t}\n\n\tif r, ok := routeFromFlag(sc.c); ok {\n\t\tif res, err := sc.route(tunnel.ID, r); err != nil {\n\t\t\tsc.log.Err(err).Str(\"route\", r.String()).Msg(routeFailMsg)\n\t\t} else {\n\t\t\tsc.log.Info().Msg(res.SuccessSummary())\n\t\t}\n\t}\n\n\tif err := sc.run(tunnel.ID); err != nil {\n\t\treturn errors.Wrap(err, \"error running tunnel\")\n\t}\n\n\treturn nil","sourceCodeStart":266,"sourceCodeEnd":302,"githubUrl":"https://github.com/cloudflare/cloudflared/blob/2253eeeb25a44a713a4b60b8ba1e1b3f377d1a0f/cmd/cloudflared/tunnel/cmd.go#L266-L302","documentation":"runAdhocNamedTunnel creates a named tunnel via the Cloudflare API when no active tunnel with that name exists; if sc.create() fails (any Tunnelstore/API error: auth, network, name conflict, quota) the error is wrapped as 'failed to create tunnel'. The secret is passed as an empty string so the API generates one, meaning failures are on the create call itself, not secret handling.","triggerScenarios":"`cloudflared tunnel run --name <name>` (or `tunnel create` ad-hoc path) where sc.tunnelActive either errored or found nothing and sc.create(name, credentialsOutputPath, \"\") then fails: expired/missing origin cert or token, Tunnelstore API 4xx/5xx, network outage, tunnel-name already used but deleted filter mismatch, or credentials-output path unwritable.","commonSituations":"Not logged in (`cloudflared tunnel login` never run) so cert.pem is missing; stale cert.pem after account change; offline/blocked network to api.cloudflare.com; running under a token-less service install where cert is absent; hitting the account's tunnel limit.","solutions":["Run `cloudflared tunnel login` (or provide TUNNEL_TOKEN) to establish valid credentials, then retry.","Check network connectivity to api.cloudflare.com and any proxy/firewall rules.","Read the wrapped inner error above this message for the specific API failure (401/403 vs 5xx vs file error).","If the name conflicts, pick a different tunnel name or delete the old tunnel via `cloudflared tunnel delete <name>`.","Verify the account has quota and the cert.pem in ~/.cloudflared belongs to the right account."],"exampleFix":"// before\ncloudflared tunnel run --name mytunnel   # fails: not logged in\n\n// after\ncloudflared tunnel login\ncloudflared tunnel run --name mytunnel","handlingStrategy":"try-catch","validationCode":"# before running\ntest -f ~/.cloudflared/cert.pem || cloudflared tunnel login\ncurl -sS -o /dev/null https://api.cloudflare.com || echo \"no egress to Cloudflare API\"","typeGuard":null,"tryCatchPattern":"if err := runTunnelCmd(); err != nil {\n    if strings.Contains(err.Error(), \"failed to create tunnel\") {\n        log.Errorf(\"tunnel create failed: %v — check cert.pem / API access\", err)\n    }\n}","preventionTips":["Run `cloudflared tunnel login` before first use; verify cert.pem exists","Confirm outbound HTTPS to api.cloudflare.com from the host","Watch the wrapped inner error to distinguish auth (401/403) vs network vs quota failures","Use TUNNEL_TOKEN-based installs where cert.pem management is impractical"],"tags":["cloudflare-api","tunnel","authentication","network"],"backgroundTag":"api-request-failed","analyzedSha":"2253eeeb25a44a713a4b60b8ba1e1b3f377d1a0f","analyzedAt":"2026-09-06T04:14:33.757Z","contentChangedAt":"2026-09-06T04:14:33.757Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}