cloudflare/cloudflared · warning

Connect to %v denied

Error message

Connect to %v denied

What it means

The fallback branch of the access-policy denial in handleConnect: the policy rejected the destination but returned no specific rule object, so the handler returns a generic 'Connect to <dest> denied' error after sending a ruleFailure reply. Like error 316, this is an intentional rejection by the configured access policy.

Source

Thrown at socks/request_handler.go:68

// 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)
	}
	defer target.Close()

View on GitHub (pinned to 2253eeeb25)

Solutions

  1. Add an explicit allow rule for the destination IP/port to the access policy
  2. Confirm with policy owners whether the destination should be reachable
  3. If you need the specific rule name in errors, configure rules so a matching deny rule reports itself (see error 316 path)
  4. Log destination addresses of denials to build the allowlist iteratively

Example fix

// before: default-deny, no allow rule
policy := iprules.NewDefault() // denies everything unmatched

// after
policy.AddRule(true, "10.0.0.0/24", 0, 65535) // allow internal range
Defensive patterns

Strategy: validation

Validate before calling

// pre-check against the same policy the server uses
if ok, rule := accessPolicy.Allowed(destIP, destPort); !ok {
    return fmt.Errorf("destination not allowlisted (rule=%v)", rule)
}

Type guard

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

Try / catch

if err := connect(dest); err != nil && err.Error() == fmt.Sprintf("Connect to %v denied", dest) {
    // default-deny hit: add an explicit allow rule
}

Prevention

When it happens

Trigger: handleConnect with a non-nil accessPolicy where accessPolicy.Allowed(...) returns (false, nil) — typically a default-deny policy with no matching rule.

Common situations: Default-deny iprule sets where the destination matched no explicit rule; clients connecting to hosts nobody thought to allowlist; newly provisioned services not yet added to policy.

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/b5d47d4e5f0cc9a8. Report an issue: GitHub.