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 addressesView on GitHub (pinned to cf7c3e4a8a)
Solutions
- 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)
- Use a public DNS name for the agent that resolves to a public IP
- If the agent must stay on a private network, ensure this is a deliberate security decision and document it
- 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
- Set conductor.a2a.client.allow-private-network=true in dev/staging if agents are on private networks
- Document the security implications of allowing private network agents
- For production, prefer public endpoints for A2A agents
- Remember: even with allow-private-network=true, cloud metadata addresses remain blocked
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
- agentUrl must use http or https, got: {scheme}
- agentUrl resolves to a cloud metadata address — SSRF blocked
- agentUrl must not be blank
- agentUrl is not a valid URL: {rawUrl} — {message}
- Access denied: path matches blocked prefix '{prefix}'
AI-assisted analysis of conductor-oss/conductor@cf7c3e4a8a (2026-08-14).
Data as JSON: /api/errors/eab2be5c22be0451.
Report an issue: GitHub.