cloudflare/cloudflared · warning

Connect to %v denied due to iprule: %s

Error message

Connect to %v denied due to iprule: %s

What it means

When an access policy is configured and its Allowed(ip, port) check rejects the connection with a matching rule, handleConnect sends a ruleFailure reply and returns this error naming the denied destination and the rule's string representation. This is an intentional policy denial, not a malfunction.

Source

Thrown at socks/request_handler.go:66

	}
}

// handleConnect is used to handle a connect command
func (h *StandardRequestHandler) handleConnect(conn io.ReadWriter, req *Request) error {
	if h.accessPolicy != nil {
		if req.DestAddr.IP == nil {
			addr, err := net.ResolveIPAddr("ip", req.DestAddr.FQDN)
			if err != nil {
				_ = sendReply(conn, ruleFailure, req.DestAddr)
				return fmt.Errorf("unable to resolve host to confirm access")
			}

			req.DestAddr.IP = addr.IP
		}
		if allowed, rule := h.accessPolicy.Allowed(req.DestAddr.IP, req.DestAddr.Port); !allowed {
			_ = sendReply(conn, ruleFailure, req.DestAddr)
			if rule != nil {
				return fmt.Errorf("Connect to %v denied due to iprule: %s", req.DestAddr, rule.String())
			}
			return fmt.Errorf("Connect to %v denied", req.DestAddr)
		}
	}

	target, localAddr, err := h.dialer.Dial(req.DestAddr.Address())
	if err != nil {
		msg := err.Error()
		resp := hostUnreachable
		if strings.Contains(msg, "refused") {
			resp = connectionRefused
		} else if strings.Contains(msg, "network is unreachable") {
			resp = networkUnreachable
		}
		if err := sendReply(conn, resp, nil); err != nil {
			return fmt.Errorf("Failed to send reply: %v", err)
		}
		return fmt.Errorf("Connect to %v failed: %v", req.DestAddr, err)

View on GitHub (pinned to 2253eeeb25)

Solutions

  1. Review the rule in the error message and adjust the iprule allowlist to include the destination
  2. Confirm the client is connecting to an intended host/port within policy
  3. Temporarily enable policy logging to see which requests hit which rules
  4. If the policy should permit it, update rule definitions passed to the handler's access policy

Example fix

// before: default-deny blocks 10.0.0.5
policy := iprules.NewDefault()

// after: add allow rule
policy.AddRule(true, "10.0.0.0/24", 0, 65535)
Defensive patterns

Strategy: validation

Validate before calling

// client side: check the destination against policy before requesting
if !policyAllows(destIP, destPort) {
    return fmt.Errorf("destination %s:%d will be denied by policy", destIP, destPort)
}

Type guard

func policyAllows(ip net.IP, port uint16) bool {
    ok, _ := accessPolicy.Allowed(ip, port)
    return ok
}

Try / catch

if err := connect(dest); err != nil && strings.Contains(err.Error(), "denied due to iprule") {
    // surface rule name to the user; do not retry
}

Prevention

When it happens

Trigger: handleConnect with a non-nil accessPolicy where accessPolicy.Allowed(req.DestAddr.IP, req.DestAddr.Port) returns (false, non-nil rule).

Common situations: Legitimate destinations blocked by an overly broad deny rule; clients requesting hosts outside the allowlist (default-deny policies); rule misconfiguration after network changes; corporate policy blocking the target port.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


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