BerriAI/litellm · warning · A2ALocalhostURLError

Agent card contains localhost/internal URL '{localhost_url}'

Error message

Agent card contains localhost/internal URL '{localhost_url}'. Retrying with base URL '{base_url}'.

What it means

An A2A agent serves a self-describing 'agent card' whose URL field may point at localhost/127.0.0.1 or an internal address. When LiteLLM follows the card's advertised URL and gets a connection error, map_a2a_exception classifies it as A2ALocalhostURLError and the retry handler rewrites the card URL back to your original api_base and resends, logging this warning. The warning therefore marks a recovered-by-retry condition, very common with containerized agents that hardcode localhost.

Source

Thrown at litellm/a2a_protocol/exception_mapping_utils.py:130

    Returns:
        A mapped LiteLLM A2A exception

    Raises:
        A2ALocalhostURLError: If the error is a connection error to a localhost URL
        A2AConnectionError: If the error is a general connection error
        A2AAgentCardError: If the error is related to agent card issues
        A2AError: For other A2A-related errors
    """
    error_str: Final = str(original_exception)

    # Check for localhost URL connection error (special case - retryable)
    if (
        card_url
        and api_base
        and A2AExceptionCheckers.is_localhost_url(card_url)
        and A2AExceptionCheckers.is_connection_error(error_str)
    ):
        raise A2ALocalhostURLError(
            localhost_url=card_url,
            base_url=api_base,
            original_error=original_exception,
            model=model,
        )

    # Check for agent card errors
    if A2AExceptionCheckers.is_agent_card_error(error_str):
        raise A2AAgentCardError(
            message=error_str,
            url=api_base,
            model=model,
        )

    # Check for general connection errors
    if A2AExceptionCheckers.is_connection_error(error_str):
        raise A2AConnectionError(
            message=error_str,

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. Let LiteLLM's built-in retry handle it — it already resends against your api_base; treat the log as a warning, not a failure
  2. Fix the agent so its card advertises an externally reachable URL (most agent frameworks expose a PUBLIC_URL / host env for this)
  3. Fix DNS/network so the advertised URL resolves from where litellm runs

Example fix

# agent env — before
A2A_HOST=localhost  # card advertises http://localhost:10001

# agent env — after
A2A_HOST=agent-svc  # card advertises http://agent-svc:10001, routable from litellm
Defensive patterns

Strategy: retry

Validate before calling

from urllib.parse import urlparse


def is_internal_url(url: str | None) -> bool:
    if not url:
        return False
    host = (urlparse(url).hostname or '').lower()
    return (
        host in {'localhost', '127.0.0.1', '0.0.0.0', '::1'}
        or host.startswith('10.')
        or host.startswith('192.168.')
        or host.startswith('172.')
    )


# pre-flight: fetch and sanitize the card before first send
card = await aget_agent_card(base_url=api_base)
if is_internal_url(getattr(card, 'url', None)):
    card.url = api_base  # rewrite so no failed attempt is needed

Try / catch

from litellm.a2a_protocol.exception_mapping_utils import (
    A2ALocalhostURLError,  # exported via the a2a_protocol package
)

try:
    resp = await asend_message(a2a_client=client, request=req, api_base=api_base)
except A2ALocalhostURLError:
    # library already retried once internally; a second escape means the
    # agent card itself must be fixed
    raise RuntimeError(f'Agent card advertises an unreachable URL for {api_base}')

Prevention

When it happens

Trigger: await asend_message(api_base='http://agent-svc:10001', ...) where the fetched card advertises 'http://localhost:10001'; any A2A call where the card URL is only routable inside the agent's own network namespace (Docker, K8s, NAT).

Common situations: Docker Compose / Kubernetes deployments of A2A agents (LangGraph Platform etc.) that publish localhost in .well-known/agent-card.json; local dev against a port-forwarded remote agent.

Related errors


AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18). Data as JSON: /api/errors/a89bed2fd9aa99dc. Report an issue: GitHub.