{"record":{"id":"0e32160d751ad286","repo":"cloudflare/cloudflared","slug":"srv-record-v-had-no-ips","errorCode":null,"errorMessage":"SRV record %v had no IPs","messagePattern":"SRV record (.+?) had no IPs","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"edgediscovery/allregions/discovery.go","lineNumber":178,"sourceCode":"\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\ttlsConfig := &tls.Config{ServerName: dotServerName}\n\t\t\treturn tls.Client(conn, tlsConfig), nil\n\t\t},\n\t}\n\tctx, cancel := context.WithTimeout(context.Background(), dotTimeout)\n\tdefer cancel()\n\treturn r.LookupSRV(ctx, srvService, srvProto, srvName)\n}\n\nfunc resolveSRV(srv *net.SRV) ([]*EdgeAddr, error) {\n\tips, err := netLookupIP(srv.Target)\n\tif err != nil {\n\t\treturn nil, errors.Wrapf(err, \"Couldn't resolve SRV record %v\", srv)\n\t}\n\tif len(ips) == 0 {\n\t\treturn nil, fmt.Errorf(\"SRV record %v had no IPs\", srv)\n\t}\n\taddrs := make([]*EdgeAddr, len(ips))\n\tfor i, ip := range ips {\n\t\tversion := V6\n\t\tif ip.To4() != nil {\n\t\t\tversion = V4\n\t\t}\n\t\taddrs[i] = &EdgeAddr{\n\t\t\tTCP:       &net.TCPAddr{IP: ip, Port: int(srv.Port)},\n\t\t\tUDP:       &net.UDPAddr{IP: ip, Port: int(srv.Port)},\n\t\t\tIPVersion: version,\n\t\t}\n\t}\n\treturn addrs, nil\n}\n\n// ResolveAddrs resolves TCP address given a list of addresses. Address can be a hostname, however, it will return at most one\n// of the hostname's IP addresses.","sourceCodeStart":160,"sourceCodeEnd":196,"githubUrl":"https://github.com/cloudflare/cloudflared/blob/2253eeeb25a44a713a4b60b8ba1e1b3f377d1a0f/edgediscovery/allregions/discovery.go#L160-L196","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["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.","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.","Use --edge to pin specific edge addresses (or --edge-ip-version to force a family that your network actually resolves) to bypass SRV discovery.","Flush the local DNS cache (ipconfig /flushdns, systemd-resolve --flush-caches) in case stale negative caching is the cause."],"exampleFix":"// before (workaround in config)\n// cloudflared tunnel run ...\n// after — pin the edge when SRV discovery yields no IPs:\n// cloudflared tunnel --edge <ip1:7844>,<ip2:7844> run <tunnel>","handlingStrategy":"retry","validationCode":"func srvHasIPs(service string) error {\n    _, addrs, err := net.LookupSRV(\"\", \"\", service)\n    if err != nil {\n        return err\n    }\n    for _, srv := range addrs {\n        ips, err := net.LookupIP(srv.Target)\n        if err == nil && len(ips) > 0 {\n            return nil // at least one SRV target resolves to IPs\n        }\n    }\n    return errors.New(\"no SRV target resolved to any IP\")\n}","typeGuard":null,"tryCatchPattern":"regions, err := allregions.ResolveEdge(log, region, ipVersion)\nif err != nil {\n    if strings.Contains(err.Error(), \"had no IPs\") || strings.Contains(err.Error(), \"Couldn't resolve SRV\") {\n        // transient DNS: back off and retry discovery\n        time.Sleep(retryBackoff)\n        return retryDiscovery()\n    }\n    return err\n}","preventionTips":["Ensure the host's resolver (or corporate DNS) can answer SRV and A/AAAA queries for Cloudflare edge domains","Test with 'nslookup -type=SRV' before deploying in locked-down networks","Flush DNS caches after network changes to avoid stale negative answers","Configure a fallback via --edge to pin edge addresses in environments with unreliable DNS"],"tags":["network","dns","srv-record","edge-discovery","cloudflared"],"backgroundTag":"dns-resolution-failed","analyzedSha":"2253eeeb25a44a713a4b60b8ba1e1b3f377d1a0f","analyzedAt":"2026-09-06T04:14:33.757Z","contentChangedAt":"2026-09-06T04:14:33.757Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}