{"record":{"id":"c43be868223125e5","repo":"Tencent/WeKnora","slug":"failed-to-connect-to-validated-addresses-for-s","errorCode":null,"errorMessage":"failed to connect to validated addresses for %s: %w","messagePattern":"failed to connect to validated addresses for (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/utils/security.go","lineNumber":860,"sourceCode":"\t\t}\n\t}\n\n\t// If we get here, all IPs are safe. Pin the connection to the validated DNS\n\t// answers; TLS still uses the request hostname for SNI/certificate checks.\n\tdialer := &net.Dialer{\n\t\tTimeout:   30 * time.Second,\n\t\tKeepAlive: 30 * time.Second,\n\t}\n\tvar lastErr error\n\tfor _, ipAddr := range ips {\n\t\tpinnedAddr := net.JoinHostPort(ipAddr.IP.String(), port)\n\t\tconn, dialErr := dialer.DialContext(ctx, network, pinnedAddr)\n\t\tif dialErr == nil {\n\t\t\treturn conn, nil\n\t\t}\n\t\tlastErr = dialErr\n\t}\n\treturn nil, fmt.Errorf(\"failed to connect to validated addresses for %s: %w\", host, lastErr)\n}\n\n// ---------------------------------------------------------------------------\n// SSRF Whitelist mechanism\n// ---------------------------------------------------------------------------\n//\n// The environment variable SSRF_WHITELIST accepts a comma-separated list of\n// allowed host patterns. Each entry can be:\n//   - An exact domain: \"example.com\"\n//   - A wildcard domain: \"*.example.com\" (matches all subdomains)\n//   - An IPv4 address: \"203.0.113.5\"\n//   - An IPv6 address: \"2001:db8::1\"\n//   - A CIDR range (v4 or v6): \"10.0.0.0/8\", \"2001:db8::/32\"\n//\n// Whitelisted entries bypass the normal SSRF checks performed by isSSRFSafeURL.\n\nvar (\n\t// ssrfWhitelistOnce protects the cold-start ENV-only path. Once","sourceCodeStart":842,"sourceCodeEnd":878,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/utils/security.go#L842-L878","documentation":"All SSRF checks passed and the dialer tried each validated (pinned) IP in turn, but every dial attempt failed; this error wraps the last dial error (%w). It is a connectivity failure at the network layer — the security gate was cleared, but no validated address would accept the connection. The underlying error is typically connection refused, timeout, or no route to host.","triggerScenarios":"Dialing a host whose service is down, firewalled, or listening on a different interface than the resolved IPs advertise; timeouts shorter than the dial timeout; security groups/NACLs blocking the port; SSRFSafeDialContext trying each pinned address and collecting the final failure (as in TestSSRFSafeDialContextRejectsRestrictedPortAtFinalSink's sink path).","commonSituations":"Service crashed or not yet started on the target host; cloud security group not open for the port; DNS stale — IPs no longer host the service; IPv6 addresses returned but the local network has no IPv6 connectivity, so all pinned attempts fail.","solutions":["Read the wrapped error: if it is connection refused, check the service is running and listening on the port; if timeout/no-route, check firewalls, security groups, and routing.","Verify connectivity from the same host (curl/nc to the resolved IP:port) to separate network issues from code issues.","Retry with backoff for transient failures (restarts, scaling events) — errors.Unwrap can tell you if it's a timeout.","If DNS answers include unreachable families (e.g. AAAA without IPv6 connectivity), fix the DNS records or enable IPv6 routing so a valid pinned address succeeds."],"exampleFix":"// before\nconn, err := utils.SSRFSafeDialContext(ctx, \"tcp\", \"api.example.com:443\") // service down, all IPs refused\n\n// after\nvar conn net.Conn\nvar err error\nfor attempt := 0; attempt < 3; attempt++ {\n    conn, err = utils.SSRFSafeDialContext(ctx, \"tcp\", \"api.example.com:443\")\n    if err == nil { break }\n    time.Sleep(time.Duration(1<<attempt) * 100 * time.Millisecond)\n}","handlingStrategy":"retry","validationCode":"// Security checks will pass if the host resolves to public IPs; check service reachability first:\nips, err := net.LookupIP(host)\nif err == nil {\n    for _, ip := range ips {\n        if c, d := net.DialTimeout(\"tcp\", net.JoinHostPort(ip.String(), port), 2*time.Second); d == nil { c.Close(); break }\n    }\n}","typeGuard":null,"tryCatchPattern":"conn, err := utils.SSRFSafeDialContext(ctx, \"tcp\", addr)\nif err != nil && strings.Contains(err.Error(), \"failed to connect to validated addresses\") {\n    var netErr net.Error\n    if errors.As(err, &netErr) && netErr.Timeout() {\n        // transient: retry with backoff\n    }\n    return nil, fmt.Errorf(\"service unreachable on validated IPs for %s: %w\", host, err)\n}","preventionTips":["Health-check target services before dialing them in request paths.","Open firewall/security-group rules for the ports you dial.","Add bounded retry with backoff for restarts and scaling events.","Keep DNS TTLs short and records current so pinned IPs stay valid.","Verify IPv6 connectivity if your records include AAAA addresses."],"tags":["network","connection-refused","dial","timeout"],"backgroundTag":"connection-refused","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}