{"record":{"id":"aafab9ce04ad6415","repo":"cloudflare/cloudflared","slug":"failed-to-parse-as-url-w","errorCode":null,"errorMessage":"failed to parse as URL: %w","messagePattern":"failed to parse as URL: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/cloudflared/access/validation.go","lineNumber":58,"sourceCode":"\t\treturn prefix + \"[\" + host + \"]\" + rest[len(host):]\n\t}\n\treturn input\n}\n\n// parseHostname will attempt to convert a user provided URL string into a string with some light error checking on\n// certain expectations from the URL.\n// Will convert all HTTP URLs to HTTPS\nfunc parseURL(input string) (*url.URL, error) {\n\tif input == \"\" {\n\t\treturn nil, errors.New(\"no input provided\")\n\t}\n\tif !strings.HasPrefix(input, \"https://\") && !strings.HasPrefix(input, \"http://\") {\n\t\tinput = fmt.Sprintf(\"https://%s\", input)\n\t}\n\tinput = bracketBareIPv6(input)\n\turl, err := url.ParseRequestURI(input)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse as URL: %w\", err)\n\t}\n\tif url.Scheme != \"https\" {\n\t\turl.Scheme = \"https\"\n\t}\n\tif url.Host == \"\" {\n\t\treturn nil, errors.New(\"failed to parse Host\")\n\t}\n\thost, err := httpguts.PunycodeHostPort(url.Host)\n\tif err != nil || host == \"\" {\n\t\treturn nil, err\n\t}\n\tif !httpguts.ValidHostHeader(host) {\n\t\treturn nil, errors.New(\"invalid Host provided\")\n\t}\n\turl.Host = host\n\treturn url, nil\n}\n","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/cloudflare/cloudflared/blob/2253eeeb25a44a713a4b60b8ba1e1b3f377d1a0f/cmd/cloudflared/access/validation.go#L40-L76","documentation":"parseURL normalizes user-supplied access input by defaulting the scheme to https:// (after bracketing bare IPv6 literals), then validates it with url.ParseRequestURI. If parsing fails it wraps the underlying error as 'failed to parse as URL'. It guarantees the access commands (ssh, app access, token generation) always operate on a well-formed HTTPS URL.","triggerScenarios":"Calling parseURL (directly or via ssh, getAppURLFromArgs, sshGen, or the anonymous arg parser) with input containing characters illegal in a URL — control characters, spaces, unescaped '%' sequences, malformed brackets like '[::1' — or an empty string.","commonSituations":"Passing hostnames with typos or trailing punctuation; pasting URLs with spaces or full-width characters from terminals/docs; unescaped '%' in passwords embedded in URLs; empty --url flags in scripts where a variable was unset.","solutions":["Check the wrapped cause (%w) for the exact parse failure — usually an invalid character or escape sequence.","Pass a plain hostname or a properly percent-encoded URL; avoid spaces and raw special characters.","Ensure the variable supplying the URL is set and non-empty in scripts (`\"${URL:?URL not set}\"`).","Use url.PathEscape/url.QueryEscape for dynamic components before composing the input string.","IPv6 hosts must be bracketed: [2001:db8::1] — though parseURL brackets bare IPv6, other malformed bracket forms still fail."],"exampleFix":"// before\n$ cloudflared access ssh --hostname \"my host example.com\"\n// after\n$ cloudflared access ssh --hostname my-host.example.com","handlingStrategy":"validation","validationCode":"func validAccessURL(input string) bool {\n\tif input == \"\" { return false }\n\tif !strings.Contains(input, \"://\") { input = \"https://\" + input }\n\tu, err := url.ParseRequestURI(input)\n\treturn err == nil && u.Host != \"\"\n}","typeGuard":null,"tryCatchPattern":"u, err := parseURL(input)\nif err != nil {\n\tvar parseErr error\n\tif errors.As(err, &parseErr) {\n\t\treturn fmt.Errorf(\"invalid access hostname %q: %w\", input, err)\n\t}\n\treturn err\n}","preventionTips":["Pass bare hostnames or fully formed https:// URLs without spaces","Percent-encode dynamic URL components","Fail fast in scripts when the URL variable is empty/unset","Prefer bracketed IPv6 literals [::1] over raw forms"],"tags":["go","url","access","validation"],"backgroundTag":"invalid-url-format","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"}