cloudflare/cloudflared · error

unable to resolve host to confirm access

Error message

unable to resolve host to confirm access

What it means

When an access control policy is configured, handleConnect must resolve the destination FQDN to an IP so the policy can be evaluated by address. If net.ResolveIPAddr fails for the hostname, the handler sends a ruleFailure reply and returns this error. The request is never dialed, so no access decision could be made.

Source

Thrown at socks/request_handler.go:58

		return h.handleBind(conn, req)
	case associateCommand:
		return h.handleAssociate(conn, req)
	default:
		if err := sendReply(conn, commandNotSupported, nil); err != nil {
			return fmt.Errorf("Failed to send reply: %v", err)
		}
		return fmt.Errorf("Unsupported command: %v", req.Command)
	}
}

// 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") {

View on GitHub (pinned to 2253eeeb25)

Solutions

  1. Fix DNS resolution on the proxy host (check /etc/resolv.conf, nameserver reachability, container dns settings)
  2. Verify the destination hostname is correct and resolvable (dig/nslookup from the proxy host)
  3. Send IP-literal destinations from the client to skip the resolve step
  4. If DNS is optional in your deployment, supply an access policy that doesn't require resolution or preload req.DestAddr.IP

Example fix

// before: hostname fails DNS in airgapped env
addr, err := net.ResolveIPAddr("ip", "internal.example.corp")

// after: ensure DNS or use IP
target := "10.0.0.5" // or fix nameserver config
addr, err := net.ResolveIPAddr("ip", target)
Defensive patterns

Strategy: fallback

Validate before calling

// pre-resolve hostname before sending the request
if _, err := net.ResolveIPAddr("ip", host); err != nil {
    return fmt.Errorf("destination %s does not resolve: %w", host, err)
}

Type guard

func isResolvable(host string) bool {
    _, err := net.ResolveIPAddr("ip", host)
    return err == nil
}

Try / catch

if err := proxy.Connect(host); err != nil && strings.Contains(err.Error(), "unable to resolve host") {
    // fall back to IP literal or fail fast in caller
}

Prevention

When it happens

Trigger: handleConnect with a non-nil accessPolicy, req.DestAddr.IP == nil, and net.ResolveIPAddr("ip", req.DestAddr.FQDN) returning an error — DNS lookup failure (NXDOMAIN, no resolver, timeout).

Common situations: Clients requesting destinations for hostnames that don't exist; the proxy host lacking DNS resolution (broken /etc/resolv.conf, offline environment, no DNS in container); typo'd hostnames in application config.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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