cloudflare/cloudflared · error
ErrURLIncompatibleWithIngress
ErrURLIncompatibleWithIngress
Error message
You can't set the --url flag (or $TUNNEL_URL) when using multiple-origin ingress rules
What it means
ErrURLIncompatibleWithIngress (public) is returned when the --url flag (or $TUNNEL_URL) is set alongside config-file ingress rules. These two routing mechanisms are mutually exclusive: --url defines a single origin, while ingress rules define multiple origins.
Source
Thrown at ingress/ingress.go:27
"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)
if err == nil {
hostname = hostView on GitHub (pinned to 2253eeeb25)
Solutions
- Remove the --url flag from the command line
- Unset the TUNNEL_URL environment variable (unset TUNNEL_URL)
- Keep the origin routing solely in the ingress rules config file
Example fix
// before TUNNEL_URL=http://localhost:8080 cloudflared tunnel ingress validate // after unset TUNNEL_URL cloudflared tunnel ingress validate
Defensive patterns
Strategy: validation
Validate before calling
if os.Getenv("TUNNEL_URL") != "" { // remove it before using ingress rules } Prevention
- Check the environment for TUNNEL_URL in containers/CI before ingress-based runs
- Use either --url OR ingress rules, never both
- Audit wrapper scripts for hardcoded --url flags
When it happens
Trigger: validateIngressCommand sees c.IsSet("url") true while the user is running an ingress-related tunnel command that also loads ingress rules from a config file.
Common situations: Environment variable TUNNEL_URL left set in the shell/container while using a config.yml with ingress rules; mixing CLI single-origin flags with a multi-origin config during migration.
Understand the failure class
Background: "mutually exclusive" flag errors: what "can't supply both nx and xx", "--raw is not compatible with -i" and "cannot be used with" mean, and how to fix them — this error's family across 29 libraries.
Related errors
- hostname and url shouldn't match. See --help for more inform
- Error validating origin URL
- Error validating --unix-socket
- No configuration file was found. Please create one, or use t
- cloudflared tunnel rule expects a single argument, the URL t
AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06).
Data as JSON: /api/errors/539d8d68647acd76.
Report an issue: GitHub.