Tencent/WeKnora · error
connection blocked: hostname suffix %s is restricted
Error message
connection blocked: hostname suffix %s is restricted
What it means
SSRFSafeDialContext blocked the connection because the lowercased hostname ends with one of the restrictedHostSuffixes. Suffix matching catches whole classes of forbidden names (e.g. ".internal", ".local", or metadata suffixes) without enumerating each host. This is a deliberate policy denial to stop lookalike subdomains from reaching restricted zones.
Source
Thrown at internal/utils/security.go:822
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
}
return dialer.DialContext(ctx, network, addr)
}
if restrictedPorts[port] {
return nil, fmt.Errorf("connection blocked: port %s is restricted", port)
}
// Check if the host is a restricted hostname
hostLower := strings.ToLower(host)
for _, restricted := range restrictedHostnames {
if hostLower == restricted {
return nil, fmt.Errorf("connection blocked: hostname %s is restricted", host)
}
}
for _, suffix := range restrictedHostSuffixes {
if strings.HasSuffix(hostLower, suffix) {
return nil, fmt.Errorf("connection blocked: hostname suffix %s is restricted", suffix)
}
}
// Resolve the hostname once, validate every answer, and then dial one of
// those exact IPs. Dialing the original hostname here would make the
// standard dialer resolve it a second time, leaving a DNS-rebinding window
// between validation and connection establishment.
ips, err := net.DefaultResolver.LookupIPAddr(ctx, host)
if err != nil {
return nil, fmt.Errorf("DNS resolution failed for %s: %w", host, err)
}
if len(ips) == 0 {
return nil, fmt.Errorf("DNS resolution returned no addresses for %s", host)
}
// Validate all resolved IPs
for _, ipAddr := range ips {
if restricted, reason := isRestrictedIP(ipAddr.IP); restricted {View on GitHub (pinned to 988cbb0330)
Solutions
- Check restrictedHostSuffixes in internal/utils/security.go to see which suffix matched, then use a hostname outside the restricted zone.
- If the suffix-restricted host is genuinely trusted, add the full host to the SSRF whitelist to bypass dial-time checks.
- Reconfigure internal DNS/service names to an allowed zone (e.g. ".example.internal" if only ".internal" is blocked).
- As a last resort, use a non-guarded dialer for that specific connection, accepting the loss of DNS-rebinding protection.
Example fix
// before conn, err := utils.SSRFSafeDialContext(ctx, "tcp", "billing.svc.cluster.local:443") // ".local" suffix restricted // after conn, err := utils.SSRFSafeDialContext(ctx, "tcp", "billing.internal.example.com:443") // or whitelist the host
Defensive patterns
Strategy: validation
Validate before calling
host, _, _ := net.SplitHostPort(addr)
h := strings.ToLower(host)
for _, suffix := range []string{".internal", ".local" /* + restrictedHostSuffixes list */} {
if strings.HasSuffix(h, suffix) {
return fmt.Errorf("hostname %s uses restricted suffix %s; rename or whitelist", host, suffix)
}
} Try / catch
conn, err := utils.SSRFSafeDialContext(ctx, "tcp", addr)
if err != nil && strings.Contains(err.Error(), "hostname suffix") {
return nil, fmt.Errorf("destination in restricted DNS zone: %w", err)
} Prevention
- Check restrictedHostSuffixes when planning internal DNS zones and service names.
- Avoid ".local" and similar commonly-restricted suffixes for services dialed by this client.
- Whitelist full hostnames (not suffixes) for trusted destinations.
- Run a config-lint step that dials all configured endpoints at deploy time.
When it happens
Trigger: Dialing through SSRFSafeDialContext / SSRFSafeGRPCDialer with a host whose name ends in a restricted suffix (e.g. "myservice.internal" when ".internal" is restricted), on the non-whitelisted path. TestSSRFSafeDialContextRejectsRestrictedPortAtFinalSink drives the final-sink code path that performs this check.
Common situations: Internal service DNS zones that collide with the restricted suffix list; Kubernetes cluster-local names like "svc.cluster.local" hitting a ".local" restriction; renaming services into a suffix the library treats as forbidden.
Related errors
- connection blocked: hostname %s is restricted
- invalid address %s: %w
- connection blocked: port %s is restricted
- unsafe MinIO endpoint: %w
- unsafe OSS endpoint: %w
AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02).
Data as JSON: /api/errors/e2c1c9c3ab495ee0.
Report an issue: GitHub.