cloudflare/cloudflared · error
%s is not a valid hostname
Error message
%s is not a valid hostname
What it means
dnsRouteFromArg validates the user-supplied hostname argument for `cloudflared tunnel route dns` with validateHostname(userHostname, true). If validation fails, it rejects the argument with '<hostname> is not a valid hostname'. The hostname must be a syntactically valid DNS name (FQDN allowed, wildcards only as the leading label).
Source
Thrown at cmd/cloudflared/tunnel/subcommands.go:957
},
buildRouteIPSubcommand(),
},
}
}
func dnsRouteFromArg(c *cli.Context, overwriteExisting bool) (cfapi.HostnameRoute, error) {
const (
userHostnameIndex = 1
expectedNArgs = 2
)
if c.NArg() != expectedNArgs {
return nil, cliutil.UsageError("Expected %d arguments, got %d", expectedNArgs, c.NArg())
}
userHostname := c.Args().Get(userHostnameIndex)
if userHostname == "" {
return nil, cliutil.UsageError("The third argument should be the hostname")
} else if !validateHostname(userHostname, true) {
return nil, errors.Errorf("%s is not a valid hostname", userHostname)
}
return cfapi.NewDNSRoute(userHostname, overwriteExisting), nil
}
func lbRouteFromArg(c *cli.Context) (cfapi.HostnameRoute, error) {
const (
lbNameIndex = 1
lbPoolIndex = 2
expectedNArgs = 3
)
if c.NArg() != expectedNArgs {
return nil, cliutil.UsageError("Expected %d arguments, got %d", expectedNArgs, c.NArg())
}
lbName := c.Args().Get(lbNameIndex)
if lbName == "" {
return nil, cliutil.UsageError("The third argument should be the load balancer name")
} else if !validateHostname(lbName, true) {
return nil, errors.Errorf("%s is not a valid load balancer name", lbName)View on GitHub (pinned to 2253eeeb25)
Solutions
- Pass a bare hostname/FQDN without scheme, path, or port: `app.example.com`.
- Place wildcards only at the start if allowed: `*.example.com`.
- Ensure the hostname belongs to a zone in your Cloudflare account so DNS routing can succeed.
- Check for hidden characters/typos; retype the hostname.
Example fix
// before cloudflared tunnel route dns my-tunnel https://app.example.com:8080 // after cloudflared tunnel route dns my-tunnel app.example.com
Defensive patterns
Strategy: validation
Validate before calling
// Go: check the hostname argument before calling `tunnel route dns`
import "net"
func validHostnameArg(h string) bool {
if h == "" || strings.ContainsAny(h, ":/@ ") {
return false
}
if net.ParseIP(h) != nil {
return false
}
labels := strings.Split(strings.TrimPrefix(h, "*."), ".")
return len(labels) >= 2
} Prevention
- Strip scheme, port, and path from hostnames before passing them.
- Keep wildcards only as the leading label.
- Confirm the hostname's zone exists in your Cloudflare account.
When it happens
Trigger: Running `cloudflared tunnel route dns <tunnel> <hostname>` where the third argument contains invalid characters, is not a valid domain (e.g. includes a scheme, path, underscore, port), is an IP address, or has a misplaced wildcard like `sub.*.example.com`.
Common situations: Passing a full URL (https://app.example.com) instead of a bare hostname, including a port (:8080), using a subdomain-only value (app) without a zone, or wildcard notation in the wrong position.
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
- dns-proxy feature is no longer supported
- invalid %s provided: %w
- Tunnel %s has already been deleted
- Invalid hostname provided
- error writing token credentials to JSON file in path %s
AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06).
Data as JSON: /api/errors/8b7f8e2d8bc0613f.
Report an issue: GitHub.