cloudflare/cloudflared · error

Hostname(actually a URL) %s has invalid ASCII encdoing %s

Error message

Hostname(actually a URL) %s has invalid ASCII encdoing %s

What it means

For URL-shaped input, ValidateHostname extracts the host portion and converts it to ASCII via idna.ToASCII (Internationalized Domain Names). This error fires when the hostname contains characters that cannot be converted to a valid IDNA ASCII form — typically invalid Unicode, labels starting with '--' (xn-- abuse), or over-long labels.

Source

Thrown at validation/validation.go:45

)

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 {
		return "", fmt.Errorf("Hostname %s is not valid", hostnameToURL)
	}
	return hostnameToURL.RequestURI(), nil

}

// ValidateUrl returns a validated version of `originUrl` with a scheme prepended (by default http://).
// Note: when originUrl contains a scheme, the path is removed:

View on GitHub (pinned to 2253eeeb25)

Solutions

  1. Use a valid, punycode-encodable hostname (convert IDN with golang.org/x/net/idna yourself or fix the characters)
  2. Ensure the URL actually contains a hostname (not empty before the port)
  3. Replace non-ASCII characters that IDNA disallows (underscores in hostnames are also rejected by strict IDNA)
  4. Pre-validate with idna.ToASCII before calling

Example fix

// before
hostname, err := validation.ValidateHostname("http://exämple_.com")
// after: punycode the IDN first
ascii, _ := idna.ToASCII("exämple.com")
hostname, err := validation.ValidateHostname("http://" + ascii)
Defensive patterns

Strategy: validation

Validate before calling

func idnaSafeHost(u string) bool {
    parsed, err := url.Parse(u)
    if err != nil { return false }
    _, err = idna.ToASCII(parsed.Hostname())
    return err == nil
}

Try / catch

host, err := validation.ValidateHostname(input)
if err != nil {
    if strings.Contains(err.Error(), "invalid ASCII") {
        return fmt.Errorf("hostname in %q cannot be IDNA-encoded; use punycode", input)
    }
    return err
}

Prevention

When it happens

Trigger: Calling ValidateHostname with a URL whose hostname fails idna.ToASCII, e.g. "http://exämple--de" style invalid labels, control characters, or an empty hostname after parsing ("http://:8080").

Common situations: Internationalized domain names with disallowed characters; typos producing empty hostnames; unicode homoglyph or mis-encoded (non-UTF8) 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


AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06). Data as JSON: /api/errors/fee02411073db637. Report an issue: GitHub.