cloudflare/cloudflared · error
failed to parse Host
Error message
failed to parse Host
What it means
After parseURL prefixes https:// and parses the input with url.ParseRequestURI, it checks that a Host component was actually captured. Input that Go's parser accepts but that yields no host (e.g. a bare path, protocol-only string, or whitespace) triggers this error, because an Access application URL must have a hostname to route to.
Source
Thrown at cmd/cloudflared/access/validation.go:64
// certain expectations from the URL.
// Will convert all HTTP URLs to HTTPS
func parseURL(input string) (*url.URL, error) {
if input == "" {
return nil, errors.New("no input provided")
}
if !strings.HasPrefix(input, "https://") && !strings.HasPrefix(input, "http://") {
input = fmt.Sprintf("https://%s", input)
}
input = bracketBareIPv6(input)
url, err := url.ParseRequestURI(input)
if err != nil {
return nil, fmt.Errorf("failed to parse as URL: %w", err)
}
if url.Scheme != "https" {
url.Scheme = "https"
}
if url.Host == "" {
return nil, errors.New("failed to parse Host")
}
host, err := httpguts.PunycodeHostPort(url.Host)
if err != nil || host == "" {
return nil, err
}
if !httpguts.ValidHostHeader(host) {
return nil, errors.New("invalid Host provided")
}
url.Host = host
return url, nil
}
View on GitHub (pinned to 2253eeeb25)
Solutions
- Provide a full hostname, e.g. `app.example.com` or `https://app.example.com`.
- Echo the exact value being passed to confirm it is non-empty and includes a host.
- If building the URL in a script, validate the host segment before calling cloudflared.
Example fix
// before
url := "https://" + os.Getenv("SUBDOMAIN") // empty -> no Host
// after
if os.Getenv("SUBDOMAIN") == "" { return errors.New("SUBDOMAIN is required") }
url := "https://" + os.Getenv("SUBDOMAIN") + ".example.com" Defensive patterns
Strategy: validation
Validate before calling
u, err := url.ParseRequestURI(input)
if err != nil || u.Host == "" {
return errors.New("input must include a hostname, e.g. https://app.example.com")
} Type guard
func hasHost(u *url.URL) bool { return u != nil && u.Host != "" } Try / catch
url, err := parseURL(input)
if err != nil {
if strings.Contains(err.Error(), "failed to parse Host") {
return fmt.Errorf("%q is not a usable hostname for access; include a host like app.example.com", input)
}
return err
} Prevention
- Ensure env vars that compose the hostname are set before interpolation.
- Pass fully-formed URLs (https://host) rather than paths or fragments.
- Test the hostname resolves (dig/host) before feeding it to access commands.
When it happens
Trigger: `cloudflared access ssh /just/a/path`, `https://` with no host, or input containing only whitespace/special characters that parses as a URL without a Host portion.
Common situations: Truncated URLs from variable interpolation (`https://$BUCKET` with BUCKET empty); pasting a URL and losing the hostname; passing a path instead of a host.
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.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- not a valid host
- no input provided
- invalid Host provided
- %s is not a valid URL
- %s doesn't have a hostname, consider adding a scheme
AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06).
Data as JSON: /api/errors/fb8de8af885c0e9b.
Report an issue: GitHub.