iflytek/astron-agent · error · OutboundPolicyError

Invalid PRIVATE_ENDPOINT_ALLOW_LIST entry

Error message

Invalid PRIVATE_ENDPOINT_ALLOW_LIST entry

What it means

OutboundPolicyError raised while parsing the PRIVATE_ENDPOINT_ALLOW_LIST environment variable during SSRF guard initialization. Each comma-separated entry must parse as an absolute HTTP(S) URL via _parse_http_url; malformed entries are rejected so the private-endpoint allow list cannot silently contain unusable or dangerous values.

Solutions

  1. Rewrite each PRIVATE_ENDPOINT_ALLOW_LIST entry as a full URL including scheme, e.g. 'https://vault.internal:8200' instead of 'vault.internal:8200'.
  2. Remove empty or junk entries (double commas, whitespace-only items) from the variable.
  3. Print/echo the raw env var in the deployment environment to spot truncation or quoting mangling (e.g. unescaped special chars in docker-compose YAML).
  4. Restart the service after fixing so from_environment() re-parses at startup.

Example fix

// before
PRIVATE_ENDPOINT_ALLOW_LIST=vault.internal:8200, db.corp
// after
PRIVATE_ENDPOINT_ALLOW_LIST=https://vault.internal:8200, https://db.corp:5432
Defensive patterns

Strategy: validation

Validate before calling

import re
URL_RE = re.compile(r"^https?://[^/?#]+$")
def validate_allow_list(raw: str) -> list[str]:
    entries = [e.strip() for e in raw.split(",") if e.strip()]
    bad = [e for e in entries if not URL_RE.match(e)]
    if bad:
        raise ValueError(f"entries must be absolute URLs without query: {bad}")
    return entries

Prevention

When it happens

Trigger: from_environment() -> _parse_private_endpoints() encounters an entry in PRIVATE_ENDPOINT_ALLOW_LIST that _parse_http_url cannot parse — e.g. a value with no scheme ('myhost.internal'), a bare IP without scheme, or garbage characters/typo.

Common situations: Operators set PRIVATE_ENDPOINT_ALLOW_LIST in deployment env/docker-compose/helm values with hostnames instead of full URLs, leave stray commas producing empty-plus-garbage entries, or copy values with typos or shell-mangled characters.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of iflytek/astron-agent@5e758547a8 (2026-09-12). Data as JSON: /api/errors/d0f3d857601d96cb. Report an issue: GitHub.

Appendix: source

Thrown at core/plugin/link/infra/tool_exector/ssrf_guard.py:259

            # Use the same IDNA normalization as aiohttp/yarl applies to request hosts.
            # Python's built-in ``idna`` codec follows IDNA2003 and would otherwise
            # collapse distinct hosts such as faß.de and fass.de.
            domains.append(_normalize_hostname(value))
        except OutboundPolicyError as exc:
            raise OutboundPolicyError("Invalid DOMAIN_BLACK_LIST entry") from exc
    return tuple(domains)


def _parse_private_endpoints(raw_value: str) -> Tuple[Endpoint, ...]:
    endpoints = []
    for entry in raw_value.split(","):
        value = entry.strip()
        if not value:
            continue
        try:
            parsed = _parse_http_url(value)
        except OutboundPolicyError as exc:
            raise OutboundPolicyError(
                "Invalid PRIVATE_ENDPOINT_ALLOW_LIST entry"
            ) from exc
        if parsed.query or ";" in parsed.path:
            raise OutboundPolicyError(
                "PRIVATE_ENDPOINT_ALLOW_LIST entries must not include params or a query"
            )
        endpoints.append(_endpoint(parsed))
    return tuple(endpoints)


def _endpoint(parsed: SplitResult) -> Endpoint:
    scheme, hostname, port = _origin(parsed.geturl())
    return scheme, hostname, port, parsed.path or "/"


def _normalize_hostname(hostname: str) -> str:
    value = hostname.strip().lower().rstrip(".")
    if _parse_ip(value) is not None:

View on GitHub (pinned to 5e758547a8)