affaan-m/ECC · error · ValueError
remote import host resolves to a non-public address
Error message
remote import host resolves to a non-public address: {host} What it means
Raised by _validate_import_url after DNS resolution when any resolved address for the hostname is private, loopback, link-local, multicast, reserved, or unspecified. This is an SSRF guard: the CLI refuses to fetch URLs whose host resolves into internal network space. It runs on every address returned by getaddrinfo, so one bad record is enough to fail.
Solutions
- Use a genuinely public HTTPS endpoint for the import.
- For local testing, host the file on a real public URL (e.g. a gist or public bucket) rather than localhost.
- Check what the hostname resolves to (dig/nslookup) and switch to a hostname with public records.
- If this is a false positive from split-horizon DNS, import the file locally via the file import path instead.
Example fix
# before url = "http://169.254.169.254/latest/meta-data" # after url = "https://raw.githubusercontent.com/org/repo/main/instincts.yaml"
Defensive patterns
Strategy: validation
Validate before calling
import ipaddress, socket
infos = socket.getaddrinfo(hostname, 443)
for info in infos:
ip = ipaddress.ip_address(info[4][0])
if not ip.is_global:
raise ValueError(f"non-public address: {ip}") Try / catch
try:
cli_import(url=source)
except ValueError as e:
if "non-public address" in str(e):
print("host resolves to a private/internal IP; use a public URL") Prevention
- Use public endpoints (raw.githubusercontent, public buckets) for imports
- Never import from localhost/127.0.0.1/169.254.x links
- Check DNS resolution if a public hostname unexpectedly resolves privately
- Treat SSRF guards as intentional; route local testing through public staging
When it happens
Trigger: Importing from https://localhost/..., https://127.0.0.1/..., https://10.x.x.x/..., https://192.168.x.x/..., https://169.254.169.254/ (cloud metadata), or a public-looking hostname that resolves to a private IP (DNS rebinding or split-horizon DNS).
Common situations: Testing against a local mock server that must now be exposed differently; internal-only URLs that were never valid for this CLI; hostnames whose DNS returns private addresses in an office network.
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
- remote import exceeds
- remote instinct imports require https URLs
- unsupported remote content type
- download failed; existing destination preserved
- download length does not match declared size
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/68acc49e7db4b369.
Report an issue: GitHub.
Appendix: source
Thrown at skills/continuous-learning-v2/scripts/instinct-cli.py:216
addr_infos = socket.getaddrinfo(parsed.hostname, parsed.port or 443, type=socket.SOCK_STREAM)
except socket.gaierror as exc:
raise ValueError(f"remote import host could not be resolved: {parsed.hostname}") from exc
for family, _, _, _, sockaddr in addr_infos:
host = sockaddr[0]
try:
ip = ipaddress.ip_address(host)
except ValueError:
continue
if (
ip.is_private
or ip.is_loopback
or ip.is_link_local
or ip.is_multicast
or ip.is_reserved
or ip.is_unspecified
):
raise ValueError(f"remote import host resolves to a non-public address: {host}")
return urllib.parse.urlunparse(parsed)
def _fetch_import_url(source: str, *, max_bytes: int = 2 * 1024 * 1024) -> str:
"""Fetch a validated remote instinct file with bounded size and timeout."""
url = _validate_import_url(source)
req = urllib.request.Request(url, headers={"User-Agent": "ECC-instinct-import/2"})
with urllib.request.urlopen(req, timeout=15) as response:
content_type = response.headers.get("Content-Type", "")
if content_type and not any(
allowed in content_type.lower()
for allowed in ("text/", "markdown", "yaml", "json", "octet-stream")
):
raise ValueError(f"unsupported remote content type: {content_type}")
data = response.read(max_bytes + 1)
if len(data) > max_bytes:
raise ValueError(f"remote import exceeds {max_bytes} bytes")View on GitHub (pinned to 8321021c54)