microsoft/semantic-kernel · error · FunctionExecutionException
The request URI scheme '{parsed_url.scheme}' is not allowed.
Error message
The request URI scheme '{parsed_url.scheme}' is not allowed. Only '{DEFAULT_ALLOWED_SCHEME}' is permitted by default. To allow this URL, add it to server_url_validation_allowed_base_urls. What it means
Thrown when allowed_base_urls is empty (no allow-list) and the request URL scheme is not https (DEFAULT_ALLOWED_SCHEME). Without an explicit allow-list, Semantic Kernel only permits HTTPS by default to reduce SSRF and plaintext-exposure risk.
Source
Thrown at python/semantic_kernel/connectors/openapi_plugin/server_url_validator.py:55
"""Validate a fully resolved OpenAPI operation URL against the supplied policy."""
options = options or ServerUrlValidationOptions()
try:
parsed_url = _parse_absolute_url(url)
except ValueError as exc:
raise FunctionExecutionException(
f"The request URI '{url}' is not allowed because it is not a valid absolute URI."
) from exc
if _matches_allowed_base_url(parsed_url, options.allowed_base_urls):
return
if options.allowed_base_urls:
raise FunctionExecutionException(
f"The request URI '{url}' is not allowed. It does not match any of the allowed base URLs."
)
if parsed_url.scheme.lower() != DEFAULT_ALLOWED_SCHEME:
raise FunctionExecutionException(
f"The request URI scheme '{parsed_url.scheme}' is not allowed. "
f"Only '{DEFAULT_ALLOWED_SCHEME}' is permitted by default. "
"To allow this URL, add it to server_url_validation_allowed_base_urls."
)
if options.allow_private_network_access:
return
await _ensure_public_host(parsed_url, dns_resolver)
def try_categorize_non_public_address(
address: str | ipaddress.IPv4Address | ipaddress.IPv6Address,
) -> 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:View on GitHub (pinned to c028a0c7dc)
Solutions
- Switch the OpenAPI server URL to https://
- If plain HTTP is required for a trusted host, add its full base URL (including the http scheme) to allowed_base_urls
- Set allow_private_network_access=True only when you intentionally target a private/loopback host over http
Example fix
# before - spec server: http://localhost:8080
await validate_server_url('http://localhost:8080/api/run') # raises 1501
# after - allow the explicit http base
options = ServerUrlValidationOptions(allowed_base_urls=['http://localhost:8080/api'])
await validate_server_url('http://localhost:8080/api/run', options) Defensive patterns
Strategy: validation
Validate before calling
from urllib.parse import urlparse
def is_https_or_allowed(url: str, allowed_base_urls: list[str]) -> bool:
scheme = urlparse(url).scheme.lower()
return scheme == 'https' or any(urlparse(url).scheme.lower() == urlparse(b).scheme.lower() for b in allowed_base_urls)
if not is_https_or_allowed(url, options.allowed_base_urls):
# force https or add an explicit http base to the allow-list
url = url.replace('http://', 'https://', 1) if not options.allowed_base_urls else url Try / catch
try:
await validate_server_url(url, options)
except FunctionExecutionException as e:
if 'permitted by default' in str(e):
# either upgrade to https or add the http base url to allowed_base_urls
... Prevention
- Author OpenAPI specs against https server URLs
- In local dev, add the explicit http base URL to allowed_base_urls rather than weakening defaults
- Avoid ftp/file schemes for plugin operations
When it happens
Trigger: An OpenAPI plugin server URL uses a non-https scheme (http://, ftp://) and no allowed_base_urls were configured. Common: http://localhost:8080 or http://internal-service in the spec.
Common situations: Local development over plain HTTP; internal services without TLS; OpenAPI spec authored against http://; CI environment without TLS termination.
Related errors
- The request URI '{url}' is not allowed. It does not match an
- The operation path resolves to '{requestAuthority}', which d
- The operation path resolves to '{requestPath}', which is out
- Path '{path}' contains a dot-segment, which could lead to pa
- The operation path resolves to '{request.scheme}://{request.
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/ac2fde0509a44030.
Report an issue: GitHub.