{"record":{"id":"ac2fde0509a44030","repo":"microsoft/semantic-kernel","slug":"the-request-uri-scheme-parsed-url-scheme-is-no","errorCode":null,"errorMessage":"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.","messagePattern":"The request URI scheme '(.+?)' is not allowed\\. Only '(.+?)' is permitted by default\\. To allow this URL, add it to server_url_validation_allowed_base_urls\\.","errorType":"exception","errorClass":"FunctionExecutionException","httpStatus":null,"severity":"error","filePath":"python/semantic_kernel/connectors/openapi_plugin/server_url_validator.py","lineNumber":55,"sourceCode":"    \"\"\"Validate a fully resolved OpenAPI operation URL against the supplied policy.\"\"\"\n    options = options or ServerUrlValidationOptions()\n    try:\n        parsed_url = _parse_absolute_url(url)\n    except ValueError as exc:\n        raise FunctionExecutionException(\n            f\"The request URI '{url}' is not allowed because it is not a valid absolute URI.\"\n        ) from exc\n\n    if _matches_allowed_base_url(parsed_url, options.allowed_base_urls):\n        return\n\n    if options.allowed_base_urls:\n        raise FunctionExecutionException(\n            f\"The request URI '{url}' is not allowed. It does not match any of the allowed base URLs.\"\n        )\n\n    if parsed_url.scheme.lower() != DEFAULT_ALLOWED_SCHEME:\n        raise FunctionExecutionException(\n            f\"The request URI scheme '{parsed_url.scheme}' is not allowed. \"\n            f\"Only '{DEFAULT_ALLOWED_SCHEME}' is permitted by default. \"\n            \"To allow this URL, add it to server_url_validation_allowed_base_urls.\"\n        )\n\n    if options.allow_private_network_access:\n        return\n\n    await _ensure_public_host(parsed_url, dns_resolver)\n\n\ndef try_categorize_non_public_address(\n    address: str | ipaddress.IPv4Address | ipaddress.IPv6Address,\n) -> tuple[bool, str]:\n    \"\"\"Return whether an IP address is non-public and the category when blocked.\"\"\"\n    ip_address = ipaddress.ip_address(address)\n\n    if isinstance(ip_address, ipaddress.IPv6Address) and ip_address.ipv4_mapped:","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/python/semantic_kernel/connectors/openapi_plugin/server_url_validator.py#L37-L73","documentation":"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.","triggerScenarios":"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.","commonSituations":"Local development over plain HTTP; internal services without TLS; OpenAPI spec authored against http://; CI environment without TLS termination.","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"],"exampleFix":"# before - spec server: http://localhost:8080\nawait validate_server_url('http://localhost:8080/api/run')  # raises 1501\n\n# after - allow the explicit http base\noptions = ServerUrlValidationOptions(allowed_base_urls=['http://localhost:8080/api'])\nawait validate_server_url('http://localhost:8080/api/run', options)","handlingStrategy":"validation","validationCode":"from urllib.parse import urlparse\n\ndef is_https_or_allowed(url: str, allowed_base_urls: list[str]) -> bool:\n    scheme = urlparse(url).scheme.lower()\n    return scheme == 'https' or any(urlparse(url).scheme.lower() == urlparse(b).scheme.lower() for b in allowed_base_urls)\n\nif not is_https_or_allowed(url, options.allowed_base_urls):\n    # force https or add an explicit http base to the allow-list\n    url = url.replace('http://', 'https://', 1) if not options.allowed_base_urls else url","typeGuard":null,"tryCatchPattern":"try:\n    await validate_server_url(url, options)\nexcept FunctionExecutionException as e:\n    if 'permitted by default' in str(e):\n        # either upgrade to https or add the http base url to allowed_base_urls\n        ...","preventionTips":["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"],"tags":["openapi","ssrf","url-validation","security","tls"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}