cloudflare/cloudflared · error

unable to create ip rule for %s: %s

Error message

unable to create ip rule for %s: %s

What it means

When an ingress rule's service is the SOCKS proxy, each entry under originRequest.ipRules is converted into an ipaccess.Rule via NewRuleByCIDR. If any rule fails to build (nil/empty prefix or malformed CIDR), validateIngress wraps the error with the service name and rejects the whole ingress config.

Source

Thrown at ingress/ingress.go:276

		} else if prefix := "http_status:"; strings.HasPrefix(r.Service, prefix) {
			statusCode, err := strconv.Atoi(strings.TrimPrefix(r.Service, prefix))
			if err != nil {
				return Ingress{}, errors.Wrap(err, "invalid HTTP status code")
			}
			if statusCode < 100 || statusCode > 999 {
				return Ingress{}, fmt.Errorf("invalid HTTP status code: %d", statusCode)
			}
			srv := newStatusCode(statusCode)
			service = &srv
		} else if r.Service == HelloWorldFlag || r.Service == HelloWorldService {
			service = new(helloWorld)
		} else if r.Service == ServiceSocksProxy {
			rules := make([]ipaccess.Rule, len(r.OriginRequest.IPRules))

			for i, ipRule := range r.OriginRequest.IPRules {
				rule, err := ipaccess.NewRuleByCIDR(ipRule.Prefix, ipRule.Ports, ipRule.Allow)
				if err != nil {
					return Ingress{}, fmt.Errorf("unable to create ip rule for %s: %s", r.Service, err)
				}
				rules[i] = rule
			}

			accessPolicy, err := ipaccess.NewPolicy(false, rules)
			if err != nil {
				return Ingress{}, fmt.Errorf("unable to create ip access policy for %s: %s", r.Service, err)
			}

			service = newSocksProxyOverWSService(accessPolicy)
		} else if r.Service == ServiceBastion || cfg.BastionMode {
			// Bastion mode will always start a Websocket proxy server, which will
			// overwrite the localService.URL field when `start` is called. So,
			// leave the URL field empty for now.
			cfg.BastionMode = true
			service = newBastionService()
		} else {
			// Validate URL services

View on GitHub (pinned to 2253eeeb25)

Solutions

  1. Fix the offending ipRule: give each entry a valid CIDR prefix (e.g. `10.0.0.0/8`) and valid ports
  2. Validate each prefix with net.ParseCIDR or an online CIDR checker before deploying
  3. Ensure YAML structure is correct so prefix fields are populated, not nil

Example fix

// before
originRequest:
  ipRules:
    - prefix: 10.0.0.0/33
      allow: true
// after
originRequest:
  ipRules:
    - prefix: 10.0.0.0/8
      allow: true
Defensive patterns

Strategy: validation

Validate before calling

for _, r := range ipRules {
	if _, _, err := net.ParseCIDR(r.Prefix); err != nil {
		return fmt.Errorf("bad ip rule prefix %q: %w", r.Prefix, err)
	}
}

Try / catch

var ing ingress.Ingress
if err := json.Unmarshal(data, &ing); err != nil {
	if strings.Contains(err.Error(), "unable to create ip rule") {
		// log the failing service + fix the ipRules entry in config
	}
	return err
}

Prevention

When it happens

Trigger: UnmarshalJSON or ParseIngress on a rule with `service: socks-proxy` where originRequest.ipRules contains a bad entry (empty prefix or unparseable CIDR string), causing ipaccess.NewRuleByCIDR to return an error.

Common situations: CIDR typos like `10.0.0.0/33` or `192.168.1/24` variants, missing `prefix` key in an ipRules entry, or YAML indentation mistakes that yield empty prefixes.

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


AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06). Data as JSON: /api/errors/09d82b8060a69cf3. Report an issue: GitHub.