microsoft/semantic-kernel · error · ValueError

Invalid {option_name}: {url}

Error message

Invalid {option_name}: {url}

What it means

Thrown by _parse_absolute_url when accessing parsed_url.port raises ValueError, i.e. the URL contains an out-of-range or non-numeric port. validate_server_url re-wraps the request-URL case into FunctionExecutionException; for allowed_base_urls the ValueError propagates from model_post_init / matching.

Source

Thrown at python/semantic_kernel/connectors/openapi_plugin/server_url_validator.py:87

) -> tuple[bool, str]:
    """Return whether an IP address is non-public and the category when blocked."""
    ip_address = ipaddress.ip_address(address)

    if isinstance(ip_address, ipaddress.IPv6Address) and ip_address.ipv4_mapped:
        ip_address = ip_address.ipv4_mapped

    if isinstance(ip_address, ipaddress.IPv4Address):
        return _try_classify_ipv4(ip_address)

    return _try_classify_ipv6(ip_address)


def _parse_absolute_url(url: str, option_name: str = "url") -> ParseResult:
    parsed_url = urlparse(url)
    try:
        parsed_url.port
    except ValueError as exc:
        raise ValueError(f"Invalid {option_name}: {url}") from exc

    if not parsed_url.scheme or not parsed_url.netloc or not parsed_url.hostname:
        raise ValueError(f"Invalid {option_name}: {url}")
    return parsed_url


def _matches_allowed_base_url(url: ParseResult, allowed_base_urls: list[str]) -> bool:
    for allowed_base_url in allowed_base_urls:
        base_url = _parse_absolute_url(allowed_base_url, option_name="allowed_base_urls")
        if url.scheme.lower() != base_url.scheme.lower():
            continue
        if (url.hostname or "").lower() != (base_url.hostname or "").lower():
            continue
        if _effective_port(url) != _effective_port(base_url):
            continue
        if _matches_path_prefix(url.path, base_url.path):
            return True

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Correct the port to an integer in the range 1-65535
  2. Omit the port to use the scheme default (443 for https, 80 for http)
  3. Validate the URL string with urllib before passing it to the connector

Example fix

# before
allowed = ['https://api.example.com:99999/v1']  # invalid port

# after
allowed = ['https://api.example.com:443/v1']  # or omit the port entirely
Defensive patterns

Strategy: validation

Validate before calling

from urllib.parse import urlparse

def has_valid_port(url: str) -> bool:
    p = urlparse(url)
    if p.port is None:
        return True  # scheme default, fine
    return 1 <= p.port <= 65535

# urlparse port access can itself raise ValueError for out-of-range ports:
def safe_port_ok(url: str) -> bool:
    try:
        _ = urlparse(url).port
        return True
    except ValueError:
        return False

if not safe_port_ok(url):
    raise ValueError(f'URL {url} has an invalid port')

Try / catch

try:
    await validate_server_url(url, options)
except FunctionExecutionException as e:
    if 'not a valid absolute URI' in str(e) or 'Invalid' in str(e):
        # fix the port in the url or allowed_base_urls
        ...

Prevention

When it happens

Trigger: A URL like https://host:99999/path (port > 65535) or https://host:abc/path (non-numeric port). Appears either as the request URL or inside a configured allowed_base_urls entry.

Common situations: Mistyped port in config or env var; placeholder text left in a port slot; OpenAPI spec server URL with a malformed port.

Related errors


AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13). Data as JSON: /api/errors/fe4ce91aff2c9af0. Report an issue: GitHub.