cloudflare/cloudflared · error
Hostname(actually a URL) %s has invalid escape characters %s
Error message
Hostname(actually a URL) %s has invalid escape characters %s
What it means
When ValidateHostname receives a value containing ':' or '%3A' it treats it as a URL rather than a bare hostname and attempts url.PathUnescape. This error fires when the percent-encoding is malformed (invalid escape sequences), so the input cannot be unescaped into a parseable URL.
Source
Thrown at validation/validation.go:37
accessDomain = "cloudflareaccess.com"
accessCertPath = "/cdn-cgi/access/certs"
accessJwtHeader = "Cf-access-jwt-assertion"
)
var (
supportedProtocols = []string{"http", "https", "rdp", "ssh", "smb", "tcp"}
validationTimeout = time.Duration(30 * time.Second)
)
func ValidateHostname(hostname string) (string, error) {
if hostname == "" {
return "", nil
}
// users gives url(contains schema) not just hostname
if strings.Contains(hostname, ":") || strings.Contains(hostname, "%3A") {
unescapeHostname, err := url.PathUnescape(hostname)
if err != nil {
return "", fmt.Errorf("Hostname(actually a URL) %s has invalid escape characters %s", hostname, unescapeHostname)
}
hostnameToURL, err := url.Parse(unescapeHostname)
if err != nil {
return "", fmt.Errorf("Hostname(actually a URL) %s has invalid format %s", hostname, hostnameToURL)
}
asciiHostname, err := idna.ToASCII(hostnameToURL.Hostname())
if err != nil {
return "", fmt.Errorf("Hostname(actually a URL) %s has invalid ASCII encdoing %s", hostname, asciiHostname)
}
return asciiHostname, nil
}
asciiHostname, err := idna.ToASCII(hostname)
if err != nil {
return "", fmt.Errorf("Hostname %s has invalid ASCII encdoing %s", hostname, asciiHostname)
}
hostnameToURL, err := url.Parse(asciiHostname)
if err != nil {View on GitHub (pinned to 2253eeeb25)
Solutions
- Pass a plain hostname (e.g. example.com) without ports, schemes, or percent-encoding
- If a URL is needed, pass a well-formed one: https://example.com:8080 — ensure % sequences are valid percent-escapes
- Decode the value yourself correctly before passing it in
- Check for stray '%' characters introduced by copy-paste and remove or fix them
Example fix
// before
hostname, err := validation.ValidateHostname("example.com%3A")
// after
hostname, err := validation.ValidateHostname("example.com") Defensive patterns
Strategy: validation
Validate before calling
func validHostOrURL(s string) bool {
if s == "" { return false }
if strings.Contains(s, ":") || strings.Contains(s, "%3A") {
unesc, err := url.PathUnescape(s)
if err != nil { return false }
_, err = url.Parse(unesc)
return err == nil
}
return true
} Try / catch
host, err := validation.ValidateHostname(input)
if err != nil {
if strings.Contains(err.Error(), "invalid escape characters") {
return fmt.Errorf("hostname %q contains malformed percent-encoding; pass a plain hostname", input)
}
return err
} Prevention
- Pass bare hostnames, not URLs, where a hostname is expected
- Avoid manual percent-encoding of hostnames
- Pre-sanitize inputs copied from logs/HTML that may contain stray '%'
When it happens
Trigger: Calling ValidateHostname with a string containing ':' or '%3A' that url.PathUnescape fails on, e.g. "example.com%3" (truncated percent-escape) or stray '%' characters in a tunnel hostname/URL argument.
Common situations: Users passing a full URL (with port/scheme) where cloudflared expects only a hostname, with hand-mangled percent-encoding; copy-pasted URLs from logs or HTML where '%' got corrupted.
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 format %s
- Hostname %s is not valid
- URL %s has invalid escape characters %s
- URL no %s has invalid format
AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06).
Data as JSON: /api/errors/e6d26dd0c92a8821.
Report an issue: GitHub.