{"record":{"id":"ef63f38cf1c6ecf8","repo":"cloudflare/cloudflared","slug":"url-s-has-invalid-format","errorCode":null,"errorMessage":"URL %s has invalid format","messagePattern":"URL (.+?) has invalid format","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"validation/validation.go","lineNumber":105,"sourceCode":"\t} else if strings.HasPrefix(originUrl, \"[\") && strings.HasSuffix(originUrl, \"]\") {\n\t\t// ParseIP doesn't recoginze [::1]\n\t\treturn validateIP(\"\", originUrl[1:len(originUrl)-1], \"\")\n\t}\n\n\thost, port, err := net.SplitHostPort(originUrl)\n\t// user might pass in an ip address like 127.0.0.1\n\tif err == nil && net.ParseIP(host) != nil {\n\t\treturn validateIP(\"\", host, port)\n\t}\n\n\tunescapedUrl, err := url.PathUnescape(originUrl)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"URL %s has invalid escape characters %s\", originUrl, unescapedUrl)\n\t}\n\n\tparsedUrl, err := url.Parse(unescapedUrl)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"URL %s has invalid format\", originUrl)\n\t}\n\n\t// if the url is in the form of host:port, IsAbs() will think host is the schema\n\tvar hostname string\n\thasScheme := parsedUrl.IsAbs() && parsedUrl.Host != \"\"\n\tif hasScheme {\n\t\terr := validateScheme(parsedUrl.Scheme)\n\t\tif err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\t\t// The earlier check for ip address will miss the case http://[::1]\n\t\t// and http://[::1]:8080\n\t\tif net.ParseIP(parsedUrl.Hostname()) != nil {\n\t\t\treturn validateIP(parsedUrl.Scheme, parsedUrl.Hostname(), parsedUrl.Port())\n\t\t}\n\t\thostname, err = ValidateHostname(parsedUrl.Hostname())\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"URL %s has invalid format\", originUrl)","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/cloudflare/cloudflared/blob/2253eeeb25a44a713a4b60b8ba1e1b3f377d1a0f/validation/validation.go#L87-L123","documentation":"After percent-decoding, validateUrlString parses the URL with url.Parse. If parsing fails (structurally malformed URL that Go's parser rejects), this error is returned. It is only reached for non-IP inputs whose percent-escapes were valid.","triggerScenarios":"ValidateUrl or NewAccessValidator called with a string url.Parse rejects, e.g. 'http://exa mple.com' (raw space in host), or an ASCII control character embedded in the URL.","commonSituations":"Whitespace accidentally included in config values (trailing spaces/newlines pasted from terminals), control characters from env vars, or corrupted config file content.","solutions":["Trim whitespace and remove control characters from the URL before passing it in","Verify the URL parses with a quick check: u, err := url.Parse(strings.TrimSpace(origin))","Fix the URL in your config/flag; quotes or spaces around the value are common culprits","If passing a hostname only, ensure it contains no spaces or special characters"],"exampleFix":"// before\norigin := \"http://example.com /path\"\nValidateUrl(origin) // invalid format\n// after\norigin := strings.TrimSpace(\"http://example.com /path\")\norigin = strings.ReplaceAll(origin, \" \", \"%20\")\nValidateUrl(origin)","handlingStrategy":"validation","validationCode":"func parseableURL(s string) bool {\n    _, err := url.Parse(strings.TrimSpace(s))\n    return err == nil\n}","typeGuard":null,"tryCatchPattern":"u, err := validation.ValidateUrl(origin)\nif err != nil {\n    return fmt.Errorf(\"config: bad origin_url %q: %w\", origin, err)\n}","preventionTips":["Trim whitespace/newlines from config values","Quote values in YAML/JSON configs to avoid stray characters","Avoid ASCII control characters in URLs from env vars"],"tags":["url","validation","parsing","configuration"],"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"}