cloudflare/cloudflared · error
Hostname patterns can have at most one wildcard character ("
Error message
Hostname patterns can have at most one wildcard character ("*") and it can only be used for subdomains, e.g. "*.example.com" What it means
errBadWildcard is returned when an ingress rule hostname pattern misuses the '*' wildcard. Cloudflared only permits a single wildcard as the leftmost label for subdomain matching, e.g. '*.example.com'. Any other placement or count of '*' is rejected during config validation.
Source
Thrown at ingress/ingress.go:25
"regexp"
"strconv"
"strings"
"github.com/pkg/errors"
"github.com/rs/zerolog"
"github.com/urfave/cli/v2"
"golang.org/x/net/idna"
"github.com/cloudflare/cloudflared/config"
"github.com/cloudflare/cloudflared/ingress/middleware"
"github.com/cloudflare/cloudflared/ipaccess"
)
var (
ErrNoIngressRules = errors.New("The config file doesn't contain any ingress rules")
ErrNoIngressRulesCLI = errors.New("No ingress rules were defined in provided config (if any) nor from the cli, cloudflared will return 503 for all incoming HTTP requests")
errLastRuleNotCatchAll = errors.New("The last ingress rule must match all URLs (i.e. it should not have a hostname or path filter)")
errBadWildcard = errors.New("Hostname patterns can have at most one wildcard character (\"*\") and it can only be used for subdomains, e.g. \"*.example.com\"")
errHostnameContainsPort = errors.New("Hostname cannot contain a port")
ErrURLIncompatibleWithIngress = errors.New("You can't set the --url flag (or $TUNNEL_URL) when using multiple-origin ingress rules")
)
const (
ServiceBastion = "bastion"
ServiceSocksProxy = "socks-proxy"
ServiceWarpRouting = "warp-routing"
)
// FindMatchingRule returns the index of the Ingress Rule which matches the given
// hostname and path. This function assumes the last rule matches everything,
// which is the case if the rules were instantiated via the ingress#Validate method.
//
// Negative index rule signifies local cloudflared rules (not-user defined).
func (ing Ingress) FindMatchingRule(hostname, path string) (*Rule, int) {
// The hostname might contain port. We only want to compare the host part with the rule
host, _, err := net.SplitHostPort(hostname)View on GitHub (pinned to 2253eeeb25)
Solutions
- Move the wildcard to the first character of the hostname: '*.example.com'
- Remove extra '*' characters so at most one exists
- If you meant a literal hostname, delete the '*' entirely
- Re-validate with 'cloudflared tunnel ingress validate' before running
Example fix
// before hostname: "api.*.example.com" // after hostname: "*.example.com"
Defensive patterns
Strategy: validation
Validate before calling
func validHostnamePattern(h string) bool { return h == "" || (len(h) > 1 && h[0] == '*' && !strings.Contains(h[1:], "*")) || !strings.Contains(h, "*") } Prevention
- Only use '*' as the leftmost label for subdomain matching
- Run 'cloudflared tunnel ingress validate' before deploying configs
- Never place wildcards mid-hostname or use more than one
When it happens
Trigger: validateHostname finds strings.LastIndex(r.Hostname, "*") > 0, i.e. a wildcard appears anywhere other than the first character, or multiple wildcards are present (e.g. 'www.*.example.com', 'a*b.example.com', '*.example.*').
Common situations: Users copying wildcard syntax from other proxies (placeholders mid-hostname), typos like '*?.example.com', or attempting multi-level wildcards in the config YAML ingress rules.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- Hostname cannot contain a port
- ErrURLIncompatibleWithIngress
- access.TeamName cannot be blank when access.audTags are pres
- allowed mail rule %q has an invalid wildcard domain
- %s is an invalid address, please make sure it has a scheme a
AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06).
Data as JSON: /api/errors/5cdfbbf606d40583.
Report an issue: GitHub.