{"record":{"id":"fc89a571e9a70a87","repo":"cloudflare/cloudflared","slug":"errnoingressrules","errorCode":"ErrNoIngressRules","errorMessage":"The config file doesn't contain any ingress rules","messagePattern":"The config file doesn't contain any ingress rules","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"ingress/ingress.go","lineNumber":22,"sourceCode":"\t\"fmt\"\n\t\"net\"\n\t\"net/url\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/pkg/errors\"\n\t\"github.com/rs/zerolog\"\n\t\"github.com/urfave/cli/v2\"\n\t\"golang.org/x/net/idna\"\n\n\t\"github.com/cloudflare/cloudflared/config\"\n\t\"github.com/cloudflare/cloudflared/ingress/middleware\"\n\t\"github.com/cloudflare/cloudflared/ipaccess\"\n)\n\nvar (\n\tErrNoIngressRules             = errors.New(\"The config file doesn't contain any ingress rules\")\n\tErrNoIngressRulesCLI          = 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\")\n\terrLastRuleNotCatchAll        = errors.New(\"The last ingress rule must match all URLs (i.e. it should not have a hostname or path filter)\")\n\terrBadWildcard                = errors.New(\"Hostname patterns can have at most one wildcard character (\\\"*\\\") and it can only be used for subdomains, e.g. \\\"*.example.com\\\"\")\n\terrHostnameContainsPort       = errors.New(\"Hostname cannot contain a port\")\n\tErrURLIncompatibleWithIngress = errors.New(\"You can't set the --url flag (or $TUNNEL_URL) when using multiple-origin ingress rules\")\n)\n\nconst (\n\tServiceBastion     = \"bastion\"\n\tServiceSocksProxy  = \"socks-proxy\"\n\tServiceWarpRouting = \"warp-routing\"\n)\n\n// FindMatchingRule returns the index of the Ingress Rule which matches the given\n// hostname and path. This function assumes the last rule matches everything,\n// which is the case if the rules were instantiated via the ingress#Validate method.\n//\n// Negative index rule signifies local cloudflared rules (not-user defined).","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/cloudflare/cloudflared/blob/2253eeeb25a44a713a4b60b8ba1e1b3f377d1a0f/ingress/ingress.go#L4-L40","documentation":"ErrNoIngressRules is returned by ingress.ParseIngress (and ParseIngressFromConfigAndCLI, parseSingleOriginService) when the configuration file contains no ingress rules at all — i.e. conf is nil or conf.Ingress is empty. cloudflared requires an ingress rules list for multi-origin configuration; without one it cannot route requests.","triggerScenarios":"Calling ingress.ParseIngress(conf) with a nil config or a config whose ingress array is empty (ingress.go:89); providing a tunnel config file with only originRequest settings and no ingress: section; remote management returning a config with zero ingress rules.","commonSituations":"User writes a config.yml with credentials and origin URL but omits the ingress: block; config generated by tooling that skips empty ingress lists; migrating from single-origin (--url) setups to file-based config without adding rules.","solutions":["Add an ingress rules block to the config file, ending with a catch-all rule (e.g. `- service: http_status:404`)","Provide single-origin via the --url flag / TUNNEL_URL instead of expecting file-based ingress","Use ParseIngressFromConfigAndCLI so CLI-derived rules are considered when the file has none","Validate the config file with `cloudflared tunnel ingress validate` before running"],"exampleFix":"// before (config.yml)\ningress: []\n// after (config.yml)\ningress:\n  - hostname: app.example.com\n    service: http://localhost:8080\n  - service: http_status:404","handlingStrategy":"validation","validationCode":"cfg, err := config.LoadFile(path)\nif err != nil { return err }\nif cfg == nil || len(cfg.Ingress) == 0 {\n    return errors.New(\"config must define at least one ingress rule\")\n}","typeGuard":"func hasIngressRules(cfg *config.Configuration) bool { return cfg != nil && len(cfg.Ingress) > 0 }","tryCatchPattern":"ingressRules, err := ingress.ParseIngress(conf)\nif errors.Is(err, ingress.ErrNoIngressRules) {\n    return fmt.Errorf(\"fix config: %w\", err)\n}","preventionTips":["Always include a catch-all `- service: http_status:404` rule","Run `cloudflared tunnel ingress validate` before deploying configs","Use ParseIngressFromConfigAndCLI so CLI flags are a fallback","Keep the ingress block in config templates"],"tags":["ingress","configuration","cloudflared"],"backgroundTag":"missing-required-config","analyzedSha":"2253eeeb25a44a713a4b60b8ba1e1b3f377d1a0f","analyzedAt":"2026-09-06T04:14:33.757Z","contentChangedAt":"2026-09-06T04:14:33.757Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}