micro/go-micro · error

push callback host %q: %w

Error message

push callback host %q: %w

What it means

After checking the scheme and host, defaultPushURLPolicy resolves the callback host via resolvePushHost. This error wraps any DNS/system resolution failure (%w), such as NXDOMAIN or resolver timeouts, prefixed with the host being resolved. It indicates the callback host could not be turned into IP addresses, so the SSRF policy cannot evaluate it.

Source

Thrown at gateway/a2a/pushsecurity.go:44

// pushLookupIP resolves a host to IPs; overridable in tests.
var pushLookupIP = net.LookupIP

// defaultPushURLPolicy is the SSRF-safe policy applied when no AllowPushURL is
// configured. It rejects non-http(s) schemes and hosts that resolve to a
// loopback, private, link-local, multicast, or unspecified address.
func defaultPushURLPolicy(u *url.URL) error {
	switch u.Scheme {
	case "http", "https":
	default:
		return fmt.Errorf("push callback scheme %q not allowed (want http or https)", u.Scheme)
	}
	host := u.Hostname()
	if host == "" {
		return fmt.Errorf("push callback url has no host")
	}
	ips, err := resolvePushHost(host)
	if err != nil {
		return fmt.Errorf("push callback host %q: %w", host, err)
	}
	if len(ips) == 0 {
		return fmt.Errorf("push callback host %q did not resolve", host)
	}
	for _, ip := range ips {
		if blockedPushIP(ip) {
			return fmt.Errorf("push callback host %q resolves to a blocked address %s", host, ip)
		}
	}
	return nil
}

func resolvePushHost(host string) ([]net.IP, error) {
	if ip := net.ParseIP(host); ip != nil {
		return []net.IP{ip}, nil
	}
	return pushLookupIP(host)
}

View on GitHub (pinned to 24529f1404)

Solutions

  1. Confirm the hostname resolves: run nslookup/dig on the exact host from the environment running the gateway.
  2. Fix typos or stray scheme/port characters in the callback URL.
  3. If the host is internal-only, ensure the gateway's DNS configuration can resolve it.
  4. Retry on transient resolver failures (the wrapped error distinguishes timeouts from NXDOMAIN).

Example fix

// before
callback := "https://webhooks.internal-net.local/hook" // NXDOMAIN from gateway DNS
// after
callback := "https://webhooks.internal.example.com/hook" // resolvable via configured DNS
Defensive patterns

Strategy: validation

Validate before calling

if _, err := net.LookupHost(host); err != nil {
	return fmt.Errorf("callback host %q does not resolve: %w", host, err)
}

Prevention

When it happens

Trigger: Calling SetPushNotificationConfig with a callback hostname that DNS cannot resolve: typo in the domain, internal-only name used from a network without that DNS zone, or the resolver is down.

Common situations: Registering webhooks with a hostname valid only inside the agent's private network while the gateway uses public DNS; DNS outage; host string includes a scheme or port by mistake (e.g. 'https://example.com' passed as host).

Related errors


AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01). Data as JSON: /api/errors/5bbfa7af2df85d63. Report an issue: GitHub.