{"record":{"id":"7414b5a5d09e62b5","repo":"cloudflare/cloudflared","slug":"namedtunnel-is-nil","errorCode":null,"errorMessage":"namedTunnel is nil","messagePattern":"namedTunnel is nil","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/cloudflared/tunnel/cmd.go","lineNumber":397,"sourceCode":"\tgo waitForSignal(graceShutdownC, log)\n\n\tconnectedSignal := signal.New(make(chan struct{}))\n\tgo notifySystemd(connectedSignal)\n\tif c.IsSet(\"pidfile\") {\n\t\tgo writePidFile(connectedSignal, c.String(\"pidfile\"), log)\n\t}\n\n\twg.Add(1)\n\tgo func() {\n\t\tdefer wg.Done()\n\t\tautoupdater := updater.NewAutoUpdater(\n\t\t\tc.Bool(cfdflags.NoAutoUpdate), c.Duration(cfdflags.AutoUpdateFreq), &listeners, log,\n\t\t)\n\t\terrC <- autoupdater.Run(ctx)\n\t}()\n\n\tif namedTunnel == nil {\n\t\treturn fmt.Errorf(\"namedTunnel is nil\")\n\t}\n\n\tlogTransport := logger.CreateTransportLoggerFromContext(c, logger.EnableTerminalLog)\n\n\tobserver := connection.NewObserver(log, logTransport)\n\n\t// Send Quick Tunnel URL to UI if applicable\n\tquickTunnelURL := namedTunnel.QuickTunnelUrl\n\tif quickTunnelURL != \"\" {\n\t\tobserver.SendURL(quickTunnelURL)\n\t}\n\n\ttunnelConfig, orchestratorConfig, err := prepareTunnelConfig(ctx, c, info, log, logTransport, observer, namedTunnel)\n\tif err != nil {\n\t\tlog.Err(err).Msg(\"Couldn't start tunnel\")\n\t\treturn err\n\t}\n\tconnectorID := tunnelConfig.ClientConfig.ConnectorID","sourceCodeStart":379,"sourceCodeEnd":415,"githubUrl":"https://github.com/cloudflare/cloudflared/blob/2253eeeb25a44a713a4b60b8ba1e1b3f377d1a0f/cmd/cloudflared/tunnel/cmd.go#L379-L415","documentation":"StartServer requires a resolved named-tunnel configuration to proceed; if `namedTunnel` is nil the process cannot build edge connections or credentials. This is an internal invariant check guarding against StartServer being invoked without tunnel credentials (e.g. token path failed to produce NamedTunnelConfig).","triggerScenarios":"Calling StartServer (directly from RunQuickTunnel or runWithCredentials paths) with a cli.Context whose named tunnel config was never populated — e.g. no `--token`, no credentials file, and no TunnelID in config, yet the run path was forced.","commonSituations":"Custom integrations or scripts calling cloudflared's StartServer programmatically; or a regression in flag/config parsing where TUNNEL_TOKEN was not forwarded (empty env var, mistyped secret key in orchestrator).","solutions":["Ensure the tunnel is started with credentials: pass `--token <token>` (or TUNNEL_TOKEN env) or a valid credentials file/TunnelID so namedTunnel is populated.","Verify the credentials file exists and parses (check `credentials-file` path and file contents).","If embedding, construct and pass a valid *supervisor.NamedTunnelConfig to StartServer instead of nil."],"exampleFix":"// before\n_ = exec.Command(\"cloudflared\", \"tunnel\", \"run\").Run()\n// after\n_ = exec.Command(\"cloudflared\", \"tunnel\", \"run\", \"--token\", os.Getenv(\"TUNNEL_TOKEN\")).Run()","handlingStrategy":"validation","validationCode":"// shell: verify credentials are resolvable before starting\n[ -n \"$TUNNEL_TOKEN\" ] || [ -f /etc/cloudflared/credentials.json ] || { echo \"no tunnel credentials\"; exit 1; }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pass --token or a credentials file on tunnel run paths.","Check that secret env vars are actually injected (not empty) in orchestrators.","Validate the credentials JSON parses before launch."],"tags":["internal","tunnel","credentials"],"backgroundTag":"missing-required-config","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"}