cloudflare/cloudflared · error
URL no %s has invalid format
Error message
URL no %s has invalid format
What it means
In the no-scheme branch, when net.SplitHostPort left host empty (input had no scheme and wasn't host:port-IP), the whole originUrl is validated as a hostname. If ValidateHostname fails, this error (note the odd 'URL no %s' wording, a typo for the URL without scheme) is returned.
Source
Thrown at validation/validation.go:133
}
// The earlier check for ip address will miss the case http://[::1]
// and http://[::1]:8080
if net.ParseIP(parsedUrl.Hostname()) != nil {
return validateIP(parsedUrl.Scheme, parsedUrl.Hostname(), parsedUrl.Port())
}
hostname, err = ValidateHostname(parsedUrl.Hostname())
if err != nil {
return "", fmt.Errorf("URL %s has invalid format", originUrl)
}
if parsedUrl.Port() != "" {
return fmt.Sprintf("%s://%s", parsedUrl.Scheme, net.JoinHostPort(hostname, parsedUrl.Port())), nil
}
return fmt.Sprintf("%s://%s", parsedUrl.Scheme, hostname), nil
} else {
if host == "" {
hostname, err = ValidateHostname(originUrl)
if err != nil {
return "", fmt.Errorf("URL no %s has invalid format", originUrl)
}
return fmt.Sprintf("%s://%s", defaultScheme, hostname), nil
} else {
hostname, err = ValidateHostname(host)
if err != nil {
return "", fmt.Errorf("URL %s has invalid format", originUrl)
}
// This is why the path is preserved when `originUrl` doesn't have a schema.
// Using `parsedUrl.Port()` here, instead of `port`, would remove the path
return fmt.Sprintf("%s://%s", defaultScheme, net.JoinHostPort(hostname, port)), nil
}
}
}
func validateScheme(scheme string) error {
for _, protocol := range supportedProtocols {
if scheme == protocol {View on GitHub (pinned to 2253eeeb25)
Solutions
- Check the scheme-less value is a valid hostname (letters, digits, hyphens, dots) or host:port
- Add an explicit scheme (http:// or ssh://) so the URL branch is taken instead of the hostname branch
- Run idna.ToASCII on the value directly to see the real validation failure hidden by this wrapper
- Fix typos or invalid characters in the config value
Example fix
// before
ValidateUrl("my_host:abc") // URL no my_host:abc has invalid format
// after
ValidateUrl("tcp://my_host:2000") // explicit supported scheme Defensive patterns
Strategy: validation
Validate before calling
func validOrigin(s string) bool {
if strings.Contains(s, ":") { return true } // has scheme or port
_, err := idna.ToASCII(s)
return err == nil && s != ""
} Try / catch
u, err := validation.ValidateUrl(origin)
if err != nil {
return fmt.Errorf("hostname %q failed validation: %w", origin, err)
} Prevention
- Always include an explicit supported scheme in origin config
- Verify scheme-less values are plain DNS hostnames
- Run idna.ToASCII on the value during config load for early feedback
When it happens
Trigger: ValidateUrl('bad_host!') or any scheme-less input whose hostname fails ValidateHostname: invalid IDNA characters, strings containing ':' that don't unescape/parse (e.g. 'localhost:port' with a non-numeric port reaching the hostname path).
Common situations: Typo'd hostnames in ingress config, scheme-less values like 'my_service:2000' where SplitHostPort succeeded (host='my_service' actually — this branch hits when host==''), or unicode hostnames in config files.
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.
Related errors
- invalid Host provided
- Hostname(actually a URL) %s has invalid escape characters %s
- Hostname(actually a URL) %s has invalid format %s
- Hostname %s is not valid
- URL %s has invalid escape characters %s
AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06).
Data as JSON: /api/errors/326af5a3563a6c3b.
Report an issue: GitHub.