ComposioHQ/composio · error · BlockedInternalUrlError

Could not resolve host "{parsed.hostname}"

Error message

Could not resolve host "{parsed.hostname}"

What it means

Raised by assert_safe_fetch_target when DNS resolution via socket.getaddrinfo returns an address entry that is not a plain string (unexpected getaddrinfo shape). It is a fail-closed guard in the SSRF-protection layer: any ambiguity in the resolved address is treated as unsafe and blocks the fetch with BlockedInternalUrlError.

Source

Thrown at python/composio/utils/url_safety.py:103

        prepared_url = requests.Request(method="GET", url=url).prepare().url
        if prepared_url is None:
            raise ValueError("Prepared URL is missing")
        parsed = urlparse(prepared_url)
        if parsed.scheme not in {"http", "https"} or not parsed.hostname:
            raise ValueError("URL must use HTTP(S) and include a hostname")
    except (requests.exceptions.RequestException, ValueError):
        raise BlockedInternalUrlError(
            "Refusing to fetch a malformed or non-http(s) URL"
        ) from None

    try:
        # Resolver order is kept: it encodes the system's address preference
        # (RFC 6724), and connecting walks it the way urllib3 would.
        addresses: t.List[str] = []
        for result in socket.getaddrinfo(parsed.hostname, None):
            address = result[4][0]
            if not isinstance(address, str):
                raise BlockedInternalUrlError(
                    f'Could not resolve host "{parsed.hostname}"'
                )
            if address not in addresses:
                addresses.append(address)
    except socket.gaierror as error:
        raise BlockedInternalUrlError(
            f'Could not resolve host "{parsed.hostname}"'
        ) from error

    for address in addresses:
        if is_blocked_ip(address):
            raise BlockedInternalUrlError(
                f'Refusing to fetch "{parsed.hostname}" because it resolves to a non-public address'
            )

    if not addresses:
        raise BlockedInternalUrlError(f'Could not resolve host "{parsed.hostname}"')

View on GitHub (pinned to 64b1b85502)

Solutions

  1. Verify how getaddrinfo is being mocked/patched in tests; return tuples whose result[4][0] is a string IP
  2. Check for socket monkey-patching (e.g. gevent, eventlet) or unusual resolver configurations
  3. Avoid hostnames that resolve via non-standard resolver backends when using safe_request
Defensive patterns

Strategy: try-catch

Try / catch

try:
    safe_request('GET', url)
except BlockedInternalUrlError as e:
    # resolution guard tripped; log and skip
    log.warning('blocked fetch: %s', e)

Prevention

When it happens

Trigger: Calling safe_request (or _pinned_request) with a URL whose hostname resolution returns a non-string sockaddr (exotic resolver/IPv6 sandbox setups). Effectively unreachable on normal CPython resolvers.

Common situations: Custom DNS resolvers, patched socket modules, or test environments mocking getaddrinfo incorrectly.

Understand the failure class

Related errors


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