conductor-oss/conductor · error · NonRetryableException

agentUrl resolves to a private/reserved address — SSRF block

Error message

agentUrl resolves to a private/reserved address — SSRF blocked: {address} (set {property}=true to allow private-network agents)

What it means

Thrown by A2AService.validateAgentUrl() when the agentUrl resolves to a private, loopback, link-local, any-local, or IPv6 Unique Local Address (fc00::/7) and the allow-private-network property is false (default is true in the constructor, but may be overridden). This SSRF guard can be disabled by setting conductor.a2a.client.allow-private-network=true. It is a NonRetryableException.

Source

Thrown at ai/src/main/java/org/conductoross/conductor/ai/a2a/A2AService.java:461

            InetAddress[] addresses = InetAddress.getAllByName(host);
            for (InetAddress addr : addresses) {
                // Cloud metadata endpoints are blocked even when private networks are allowed.
                if (isMetadataAddress(addr)) {
                    A2AMetrics.ssrfBlocked();
                    throw new NonRetryableException(
                            "agentUrl resolves to a cloud metadata address — SSRF blocked: "
                                    + addr.getHostAddress());
                }
                if (allowPrivateNetwork) {
                    continue;
                }
                if (addr.isLoopbackAddress()
                        || addr.isSiteLocalAddress()
                        || addr.isLinkLocalAddress()
                        || addr.isAnyLocalAddress()
                        || isUniqueLocalIpv6(addr)) {
                    A2AMetrics.ssrfBlocked();
                    throw new NonRetryableException(
                            "agentUrl resolves to a private/reserved address — SSRF blocked: "
                                    + addr.getHostAddress()
                                    + " (set "
                                    + ALLOW_PRIVATE_NETWORK_PROPERTY
                                    + "=true to allow private-network agents)");
                }
            }
        } catch (NonRetryableException e) {
            throw e;
        } catch (Exception e) {
            throw new NonRetryableException(
                    "agentUrl is not a valid URL: " + rawUrl + " — " + e.getMessage(), e);
        }
    }

    /**
     * Cloud metadata endpoints, blocked even when private networks are allowed: IPv4 link-local
     * 169.254.0.0/16 (AWS IMDS 169.254.169.254, ECS 169.254.170.2) and the IPv6 metadata addresses

View on GitHub (pinned to cf7c3e4a8a)

Solutions

  1. Set the Spring property conductor.a2a.client.allow-private-network=true to allow private-network agents (the default is already true per the constructor, check if it was overridden to false)
  2. Use a public DNS name for the agent that resolves to a public IP
  3. If the agent must stay on a private network, ensure this is a deliberate security decision and document it
  4. Note: even with allow-private-network=true, cloud metadata addresses (169.254.x.x) remain blocked

Example fix

# before: property not set or explicitly false
# conductor.a2a.client.allow-private-network=false
# after
conductor.a2a.client.allow-private-network=true
Defensive patterns

Strategy: validation

Validate before calling

// Check if the URL will be blocked by SSRF rules
// If using private network agents, set the property first:
// conductor.a2a.client.allow-private-network=true
// Then validate:
a2aService.validateAgentUrl(agentUrl);

Try / catch

try {
    a2aService.validateAgentUrl(agentUrl);
} catch (NonRetryableException e) {
    if (e.getMessage().contains("private/reserved address")) {
        // If this is expected (internal agent), enable private network access
        log.warn("Agent URL blocked by SSRF. If using internal agents, "
            + "set conductor.a2a.client.allow-private-network=true");
    }
    throw e;
}

Prevention

When it happens

Trigger: The agentUrl hostname resolves to an RFC-1918 address (10.x, 172.16-31.x, 192.168.x), loopback (127.x), link-local, 0.0.0.0, or IPv6 ULA — and conductor.a2a.client.allow-private-network is not set to true. The message includes the resolved IP and the property name to override.

Common situations: Testing with a local agent at http://localhost:8080 or http://127.0.0.1:port. The agent is deployed on an internal/private network. A development or staging environment where agents are on RFC-1918 addresses.

Related errors


AI-assisted analysis of conductor-oss/conductor@cf7c3e4a8a (2026-08-14). Data as JSON: /api/errors/eab2be5c22be0451. Report an issue: GitHub.