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

  1. Retry the request — a fresh validation cycle will pin the new address
  2. Check whether a proxy/VPN is intercepting connections and disable it for this host
  3. Confirm DNS stability (dig +short repeatedly) for the target host
  4. 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

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


AI-assisted analysis of ComposioHQ/composio@64b1b85502 (2026-08-28). Data as JSON: /api/errors/cc2518b2e6541e74. Report an issue: GitHub.