{"record":{"id":"10ca6cc3dcff73b4","repo":"cloudflare/cloudflared","slug":"w-v","errorCode":null,"errorMessage":"%w: %v","messagePattern":"%w: %v","errorType":"validation","errorClass":"ErrInvalidTunnelID","httpStatus":null,"severity":"error","filePath":"cmd/cloudflared/cliutil/management.go","lineNumber":51,"sourceCode":"\tvar apiURL string\n\tif userCreds.IsFEDEndpoint() {\n\t\tapiURL = credentials.FedRampBaseApiURL\n\t} else {\n\t\tapiURL = c.String(cfdflags.ApiURL)\n\t}\n\n\tclient, err := userCreds.Client(apiURL, buildInfo.UserAgent(), log)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\ttunnelIDString := c.Args().First()\n\tif tunnelIDString == \"\" {\n\t\treturn \"\", ErrNoTunnelID\n\t}\n\ttunnelID, err := uuid.Parse(tunnelIDString)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"%w: %v\", ErrInvalidTunnelID, err)\n\t}\n\n\ttoken, err := client.GetManagementToken(tunnelID, res)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn token, nil\n}\n\n// CreateStderrLogger creates a logger that outputs to stderr to avoid interfering with stdout\nfunc CreateStderrLogger(c *cli.Context) *zerolog.Logger {\n\tlevel, levelErr := zerolog.ParseLevel(c.String(cfdflags.LogLevel))\n\tif levelErr != nil {\n\t\tlevel = zerolog.InfoLevel\n\t}\n\tvar writer io.Writer\n\tswitch c.String(cfdflags.LogFormatOutput) {","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/cloudflare/cloudflared/blob/2253eeeb25a44a713a4b60b8ba1e1b3f377d1a0f/cmd/cloudflared/cliutil/management.go#L33-L69","documentation":"GetManagementToken validates the tunnel ID passed as a CLI argument before requesting a management token. When uuid.Parse fails, the raw error is wrapped with ErrInvalidTunnelID via fmt.Errorf(\"%w: %v\", ErrInvalidTunnelID, err), producing an error chain whose message renders literally as '%w: %v: <parse error>'. It signals the user supplied a string that is not a valid RFC-4122 UUID.","triggerScenarios":"Calling GetManagementToken (via tokenCommand, managementTokenCommand, or buildURL) with c.Args().First() that is empty-adjacent garbage: a truncated UUID, a tunnel name instead of an ID, extra whitespace, or a UUID with wrong formatting (braces, no hyphens variant mismatch with uuid.Parse).","commonSituations":"Users paste a tunnel name or partial ID from the dashboard; scripts pass shell variables that were never set; users on older cloudflared versions where tunnel names were accepted for `cloudflared tunnel token`.","solutions":["Run `cloudflared tunnel list` and copy the full UUID as the argument instead of a tunnel name","Validate the ID with github.com/google/uuid.Parse before invoking the command","Trim whitespace and strip surrounding quotes/braces from the argument","Upgrade or downgrade cloudflared to a version where tunnel-name lookup for the token command is supported, if relying on names"],"exampleFix":"// before\ncloudflared tunnel token my-tunnel\n// after\ncloudflared tunnel token 570d3f16-e26a-4e1b-bde1-3c9e4b0a1f2b","handlingStrategy":"validation","validationCode":"import \"github.com/google/uuid\"\n\nif id := c.Args().First(); uuid.Validate(id) != nil {\n    return fmt.Errorf(\"tunnel ID must be a UUID, got %q; run 'cloudflared tunnel list'\", id)\n}","typeGuard":"func isValidTunnelID(s string) bool {\n    _, err := uuid.Parse(strings.TrimSpace(s))\n    return err == nil\n}","tryCatchPattern":null,"preventionTips":["Always pass the UUID from `cloudflared tunnel list`, never the tunnel name","Trim and dequote CLI arguments before passing them to commands","Validate UUID format in shell scripts with a regex before invoking cloudflared","Pin the cloudflared version in automation so argument semantics do not shift"],"tags":["cli","uuid","validation"],"backgroundTag":"invalid-cli-argument","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"}