iflytek/astron-agent · error · RemoteResourcePolicyError

Remote resource hostname is invalid

Error message

Remote resource hostname is invalid

What it means

RemoteResourcePolicyError raised by _normalize_hostname when yarl.URL.build() rejects the hostname string. yarl enforces RFC-compliant host syntax (it rejects characters like '_', empty strings after stripping, spaces, and other invalid characters that Python's urlsplit alone would accept). This normalizer is used by fetch_public_resource, _validate_resource_url, and _is_configured_storage_url.

Solutions

  1. Replace the hostname with an RFC-valid name (letters, digits, hyphens; underscores are not valid in hostnames)
  2. If you control DNS/naming, rename the host or use the IP literal (which bypasses yarl normalization via the _parse_ip path)
  3. Percent-encode is not allowed in hostnames — instead register a DNS alias (CNAME) without underscores

Example fix

// before
url = "http://my_service.internal:8080/file"  # underscore host
await fetch_public_resource(url)
// after
url = "http://my-service.internal:8080/file"  # or http://10.0.0.5:8080/file
await fetch_public_resource(url)
Defensive patterns

Strategy: validation

Validate before calling

import re
HOST_RE = re.compile(r"^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$", re.I)
def is_valid_hostname(host: str) -> bool:
    return bool(host) and "_" not in host and HOST_RE.fullmatch(host) is not None

Try / catch

from plugin.aitools.common.clients.safe_download import RemoteResourcePolicyError
try:
    data = await fetch_public_resource(url)
except RemoteResourcePolicyError as e:
    if "hostname is invalid" in str(e):
        log.error("URL host fails RFC hostname rules: %s", url)
    raise

Prevention

When it happens

Trigger: A URL whose hostname contains characters yarl refuses, such as underscores ('my_host.example.com'), spaces, or other non-RFC characters, passed to fetch_public_resource or validated against the configured S3 storage origin.

Common situations: Internal hostnames with underscores in dev environments (common legacy naming); URLs built from env vars containing whitespace; typos like double dots or trailing punctuation.

Understand the failure class

Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.

Related errors


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

Appendix: source

Thrown at core/plugin/aitools/common/clients/safe_download.py:235

        )
    if "\\" in parsed.netloc:
        raise RemoteResourcePolicyError("Remote resource URL authority is invalid")
    if parsed.fragment:
        raise RemoteResourcePolicyError(
            "Remote resource URL must not include a fragment"
        )
    if port is not None and not 1 <= port <= 65535:
        raise RemoteResourcePolicyError("Remote resource URL port is invalid")


def _normalize_hostname(hostname: str) -> str:
    value = hostname.strip().lower().rstrip(".")
    if _parse_ip(value) is not None:
        return value
    try:
        normalized = URL.build(scheme="http", host=value).raw_host
    except (TypeError, ValueError, UnicodeError) as exc:
        raise RemoteResourcePolicyError("Remote resource hostname is invalid") from exc
    if not normalized:
        raise RemoteResourcePolicyError("Remote resource hostname is invalid")
    return normalized.rstrip(".")


def _parse_ip(value: str) -> Optional[IpAddress]:
    try:
        return ipaddress.ip_address(value)
    except ValueError:
        return None


def _validate_destination_address(
    address: IpAddress,
    *,
    allow_private_storage: bool,
) -> None:
    canonical = _canonical_address(address)

View on GitHub (pinned to 5e758547a8)