cloudflare/cloudflared · error

SRV record %v had no IPs

Error message

SRV record %v had no IPs

What it means

resolveSRV resolves each SRV record's target hostname to IP addresses when building the list of Cloudflare edge addresses. This error is thrown when DNS successfully returns the SRV record (so the SRV lookup itself worked), but net.LookupIP for the SRV target yields zero IPs. In other words, the edge service hostname exists in DNS but currently has no address records behind it, so no EdgeAddr can be constructed for it.

Source

Thrown at edgediscovery/allregions/discovery.go:178

			if err != nil {
				return nil, err
			}
			tlsConfig := &tls.Config{ServerName: dotServerName}
			return tls.Client(conn, tlsConfig), nil
		},
	}
	ctx, cancel := context.WithTimeout(context.Background(), dotTimeout)
	defer cancel()
	return r.LookupSRV(ctx, srvService, srvProto, srvName)
}

func resolveSRV(srv *net.SRV) ([]*EdgeAddr, error) {
	ips, err := netLookupIP(srv.Target)
	if err != nil {
		return nil, errors.Wrapf(err, "Couldn't resolve SRV record %v", srv)
	}
	if len(ips) == 0 {
		return nil, fmt.Errorf("SRV record %v had no IPs", srv)
	}
	addrs := make([]*EdgeAddr, len(ips))
	for i, ip := range ips {
		version := V6
		if ip.To4() != nil {
			version = V4
		}
		addrs[i] = &EdgeAddr{
			TCP:       &net.TCPAddr{IP: ip, Port: int(srv.Port)},
			UDP:       &net.UDPAddr{IP: ip, Port: int(srv.Port)},
			IPVersion: version,
		}
	}
	return addrs, nil
}

// ResolveAddrs resolves TCP address given a list of addresses. Address can be a hostname, however, it will return at most one
// of the hostname's IP addresses.

View on GitHub (pinned to 2253eeeb25)

Solutions

  1. Retry the tunnel connection — edge SRV/IP records are dynamic and an empty answer is often transient; cloudflared's connection loop will re-run EdgeDiscovery.
  2. Verify DNS resolution on the host: 'nslookup -type=SRV _v2-origintunneld._tcp.argotunnel.com' and resolve the returned target manually; fix /etc/resolv.conf or the corporate resolver if answers are empty or wrong.
  3. Use --edge to pin specific edge addresses (or --edge-ip-version to force a family that your network actually resolves) to bypass SRV discovery.
  4. Flush the local DNS cache (ipconfig /flushdns, systemd-resolve --flush-caches) in case stale negative caching is the cause.

Example fix

// before (workaround in config)
// cloudflared tunnel run ...
// after — pin the edge when SRV discovery yields no IPs:
// cloudflared tunnel --edge <ip1:7844>,<ip2:7844> run <tunnel>
Defensive patterns

Strategy: retry

Validate before calling

func srvHasIPs(service string) error {
    _, addrs, err := net.LookupSRV("", "", service)
    if err != nil {
        return err
    }
    for _, srv := range addrs {
        ips, err := net.LookupIP(srv.Target)
        if err == nil && len(ips) > 0 {
            return nil // at least one SRV target resolves to IPs
        }
    }
    return errors.New("no SRV target resolved to any IP")
}

Try / catch

regions, err := allregions.ResolveEdge(log, region, ipVersion)
if err != nil {
    if strings.Contains(err.Error(), "had no IPs") || strings.Contains(err.Error(), "Couldn't resolve SRV") {
        // transient DNS: back off and retry discovery
        time.Sleep(retryBackoff)
        return retryDiscovery()
    }
    return err
}

Prevention

When it happens

Trigger: EdgeDiscovery calling resolveSRV for a _vpc-origins.../_origin... SRV record whose target (e.g. a region-specific hostname) resolves via DNS but whose A/AAAA lookup returns an empty set — netLookupIP succeeds with no error yet len(ips) == 0.

Common situations: Transient DNS responses from recursive resolvers that return NXDOMAIN-like empty answers; broken or overly restrictive corporate DNS/VPN setups filtering Cloudflare edge records; IPv6-only or IPv4-only networks where one address family is missing and the resolver returns nothing usable; stale local DNS caches after Cloudflare changes edge records.

Related errors


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