cloudflare/cloudflared · error

Hostname %s is not valid

Error message

Hostname %s is not valid

What it means

After IDNA conversion succeeds, ValidateHostname parses the ASCII hostname with url.Parse and returns its RequestURI. This error fires when the converted hostname cannot be parsed as a URL — a rare state indicating the IDNA output itself is structurally unparseable.

Source

Thrown at validation/validation.go:56

		}
		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:
//
//	ValidateUrl("https://localhost:8080/api/") => "https://localhost:8080"
//
// but when it does not, the path is preserved:
//
//	ValidateUrl("localhost:8080/api/") => "http://localhost:8080/api/"
//
// This is arguably a bug, but changing it might break some cloudflared users.
func ValidateUrl(originUrl string) (*url.URL, error) {
	urlStr, err := validateUrlString(originUrl)
	if err != nil {

View on GitHub (pinned to 2253eeeb25)

Solutions

  1. Verify the hostname is a simple ASCII name (letters, digits, hyphens, dots) and retry
  2. Inspect the converted value (%s in the message) to see what IDNA produced and fix the original input
  3. Pre-validate with url.Parse(idna.ToASCII(hostname)) before calling
  4. Fall back to the IP address if hostname validation keeps failing

Example fix

// before
hostname, err := validation.ValidateHostname("bad\x00name")
// after
hostname, err := validation.ValidateHostname("goodname.example.com")
Defensive patterns

Strategy: validation

Validate before calling

func parsesAsURL(h string) bool {
    ascii, err := idna.ToASCII(h)
    if err != nil { return false }
    _, err = url.Parse(ascii)
    return err == nil
}

Try / catch

host, err := validation.ValidateHostname(input)
if err != nil {
    if strings.Contains(err.Error(), "is not valid") {
        return fmt.Errorf("hostname %q failed post-conversion URL parse", input)
    }
    return err
}

Prevention

When it happens

Trigger: Calling ValidateHostname with a plain hostname whose idna.ToASCII output fails url.Parse — e.g. pathological inputs where the punycode conversion yields control characters or the input contains characters url.Parse rejects.

Common situations: Hostnames with embedded characters that survive IDNA conversion but break URL parsing; extreme edge cases with mis-encoded byte sequences in config values.

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/b3bca09150f86ee3. Report an issue: GitHub.