ComposioHQ/composio · error · BlockedInternalUrlError
Refusing to talk to "{hostname}": the connection was establi
Error message
Refusing to talk to "{hostname}": the connection was established to {peer}, not to the validated address {address} What it means
After DNS validation, the request is pinned to a specific validated IP via a custom HTTPAdapter. _assert_pinned_peer verifies via the TLS peer certificate that the host actually served by the connection matches the pinned address; a mismatch (DNS change mid-flight / rebinding) fails closed and the socket is closed.
Source
Thrown at python/composio/utils/url_safety.py:290
signals ``Connection: close``, while the body stays readable.
"""
try:
peer = sock.getpeername()[0]
except (AttributeError, OSError, IndexError):
return
try:
connected_to_pinned = ipaddress.ip_address(peer) == ipaddress.ip_address(
address
)
except ValueError:
connected_to_pinned = peer == address
if connected_to_pinned:
return
sock.close()
raise BlockedInternalUrlError(
f'Refusing to talk to "{hostname}": the connection was established to '
f"{peer}, not to the validated address {address}"
)
def _proxy_applies(url: str, proxies: t.Optional[t.Mapping[str, str]]) -> bool:
"""Whether Requests would send ``url`` through a proxy.
Requests honours ``HTTP_PROXY``/``HTTPS_PROXY``/``ALL_PROXY`` (minus
``NO_PROXY``) by default. Through a proxy the socket is dialled to the
*proxy*, so pinning the target address would connect to the wrong host
entirely.
Residual: proxied requests keep only the pre-flight check, because the
proxy resolves the hostname itself and the SDK cannot see or pin that
resolution. A rebinding window therefore remains for callers that run
behind a proxy — including one inherited from the environment.
"""View on GitHub (pinned to 64b1b85502)
Solutions
- Retry the request — a fresh validation cycle will pin the new address
- Check whether a proxy/VPN is intercepting connections and disable it for this host
- Confirm DNS stability (dig +short repeatedly) for the target host
- If using a local proxy, exclude the target from proxying (NO_PROXY / trust_env=False semantics)
Defensive patterns
Strategy: retry
Try / catch
for attempt in range(3):
try:
return safe_request('GET', url)
except BlockedInternalUrlError as e:
if 'not to the validated address' not in str(e) or attempt == 2:
raise
time.sleep(0.5) # DNS changed mid-flight; revalidate on retry Prevention
- Use stable-DNS hostnames (low churn) for fetched targets
- Disable transparent proxies/VPNs that rewrite connections
When it happens
Trigger: DNS answer changing between validation and connection (TOCTOU rebinding attack), or environments where the adapter's connection lands on a different address (some proxy/transparent NAT setups). Reproduce via test_peer_mismatch_fails_closed.
Common situations: DNS-rebinding attacks against the fetch helper, rotating DNS with short TTLs, captive portals / transparent proxies rewriting connections.
Related errors
- Could not resolve host "{parsed.hostname}"
- Refusing to fetch "{parsed.hostname}" because it resolves to
- Unsafe path component: {e}
- Refusing to build a path from an empty or non-string {label}
- Refusing to build a path from a {label} containing path sepa
AI-assisted analysis of ComposioHQ/composio@64b1b85502 (2026-08-28).
Data as JSON: /api/errors/cc2518b2e6541e74.
Report an issue: GitHub.