micro/go-micro · error
push callback: refusing to connect to blocked address %s
Error message
push callback: refusing to connect to blocked address %s
What it means
pushDialControl rejects dialing addresses whose parsed IP is in the blocked set (private, loopback, link-local ranges per blockedPushIP). This SSRF protection prevents push notifications from being used to reach internal infrastructure. The error is raised at connect time when the callback target resolves to a forbidden address.
Source
Thrown at gateway/a2a/pushsecurity.go:91
ip.IsInterfaceLocalMulticast() ||
ip.IsMulticast() ||
ip.IsUnspecified()
}
// pushDialControl runs after DNS resolution, immediately before connect, on the
// resolved address — so it blocks a host that passed URL validation but was
// rebound to an internal IP (DNS rebinding).
func pushDialControl(_, address string, _ syscall.RawConn) error {
host, _, err := net.SplitHostPort(address)
if err != nil {
return err
}
ip := net.ParseIP(host)
if ip == nil {
return fmt.Errorf("push callback: cannot parse dial address %q", address)
}
if blockedPushIP(ip) {
return fmt.Errorf("push callback: refusing to connect to blocked address %s", ip)
}
return nil
}
// pushGuardClient is the HTTP client used for default-policy push delivery. Its
// dialer refuses connections to blocked addresses at connect time.
var pushGuardClient = &http.Client{
Timeout: 10 * time.Second,
Transport: &http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: (&net.Dialer{
Timeout: 5 * time.Second,
Control: pushDialControl,
}).DialContext,
},
}
// checkPushURL validates a callback URL against the dispatcher's effectiveView on GitHub (pinned to 24529f1404)
Solutions
- Point the push callback at a public, non-blocked IP address.
- Expose the local receiver via a public tunnel/host and use that public address in the callback URL.
- If internal callbacks are intentionally required, configure a custom AllowPushURL policy / dial control that explicitly allows the specific internal range.
Example fix
// before setPushConfig(task, "http://127.0.0.1:9090/push") // after setPushConfig(task, "https://push.example.com/push") // public address, not blocked
Defensive patterns
Strategy: validation
Validate before calling
u, _ := url.Parse(callbackURL)
ip := net.ParseIP(u.Hostname())
if ip != nil && (ip.IsLoopback() || ip.IsPrivate() || ip.IsLinkLocalUnicast()) {
return fmt.Errorf("callback %s targets a blocked address", ip)
} Type guard
func isPublicIP(rawURL string) bool {
u, err := url.Parse(rawURL)
if err != nil { return false }
ip := net.ParseIP(u.Hostname())
return ip != nil && !ip.IsLoopback() && !ip.IsPrivate() && !ip.IsLinkLocalUnicast()
} Prevention
- Never point push callbacks at localhost, private ranges, or metadata endpoints.
- Expose local test receivers through a public tunnel instead of using 127.0.0.1.
- Document any custom AllowPushURL policy relaxations and restrict them to explicit CIDR allowlists.
When it happens
Trigger: A push callback URL points at (or resolves to) a blocked IP such as 127.0.0.1, 10.x.x.x, 172.16.x.x, 192.168.x.x, or 169.254.169.254, and a push delivery attempt dials it under the default SSRF policy.
Common situations: Developers testing against a local push receiver on localhost; misconfigured callbacks pointing at internal cluster services; attackers supplying callback URLs targeting cloud metadata endpoints (169.254.169.254).
Related errors
- push callback scheme %q not allowed (want http or https)
- push callback host %q resolves to a blocked address %s
- push callback: cannot parse dial address %q
- ap2: mandate signature verification failed
- invalid push callback url: %w
AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01).
Data as JSON: /api/errors/524f12a8d6aa8d42.
Report an issue: GitHub.