microsoft/semantic-kernel · error · InvalidOperationException
Sending requests to host
Error message
Sending requests to host '{uri.Host}' is not allowed. Add the host to AllowedDomains. What it means
Thrown by SessionsPythonPlugin.SendAsync when the resolved host of the Code Interpreter pool management endpoint is not present in SessionsPythonSettings.AllowedDomains. The plugin enforces an explicit domain allowlist so requests are never sent to unintended hosts. If AllowedDomains is null/empty or does not contain uri.Host (case-insensitive), the request is rejected before any HTTP call is made.
Solutions
- Add the exact host reported in the message to SessionsPythonSettings.AllowedDomains (case-insensitive match, host only, no scheme/port).
- If AllowedDomains was null, initialize it with your Code Interpreter management endpoint host, e.g. new List<string> { "<region>.codeinterpreter.azure.com" }.
- Verify _poolManagementEndpoint is correct in your configuration; a wrong endpoint yields an unexpected host not in the allowlist.
- If you intentionally need to allow all hosts (dev/test only), add the specific hosts you use; there is no wildcard bypass shown in SendAsync, so keep the list aligned with every environment.
Example fix
// before
var settings = new SessionsPythonSettings
{
PoolManagementEndpoint = new Uri("https://my-pool.eastus.codeinterpreter.azure.com")
};
// after
var settings = new SessionsPythonSettings
{
PoolManagementEndpoint = new Uri("https://my-pool.eastus.codeinterpreter.azure.com"),
AllowedDomains = new List<string> { "my-pool.eastus.codeinterpreter.azure.com" }
}; Defensive patterns
Strategy: validation
Validate before calling
var host = new Uri(settings.PoolManagementEndpoint).Host;
if (settings.AllowedDomains?.Contains(host, StringComparer.OrdinalIgnoreCase) != true)
throw new InvalidOperationException(
$"AllowedDomains must contain the pool management host '{host}' before using SessionsPythonPlugin."); Try / catch
try
{
await plugin.RunCodeAsync(code);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("AllowedDomains"))
{
logger.LogError(ex, "Code Interpreter host is not allowlisted. Add it to SessionsPythonSettings.AllowedDomains.");
} Prevention
- Always populate AllowedDomains in the same place you set PoolManagementEndpoint.
- Derive AllowedDomains programmatically from the endpoint host instead of hardcoding a separate value.
- Add a startup/config validation step that fails fast when the allowlist is null or empty.
- When changing environments (dev/staging/prod), re-check that each region's host is in the allowlist.
When it happens
Trigger: Any SessionsPythonPlugin API call (e.g. RunCodeAsync) that invokes SendAsync where the host from new Uri(_poolManagementEndpoint, pathWithQueryString) is not in _settings.AllowedDomains — most often because AllowedDomains was never configured or lists the wrong host (e.g. missing a project-specific *.openai.azure.com or codeinterpreter endpoint hostname).
Common situations: Forgetting to set AllowedDomains at all when constructing SessionsPythonSettings; copying a sample config whose domain differs from your deployed region/host; a redirect or different pool management hostname than the one allowlisted; using localhost in dev while allowlisting only production domains (or vice versa); host casing or port variants you assumed were covered.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- Agent with name not found.
- Max level of traversing payload properties of operation is…
- and cannot be used together.
- Neither of the media types of
- The address ' ' is not allowed for the ' ' gRPC operation…
AI-assisted analysis of microsoft/semantic-kernel@ca40aa7226 (2026-09-20).
Data as JSON: /api/errors/69f3b54598946d12.
Report an issue: GitHub.
Appendix: source
Thrown at dotnet/src/Plugins/Plugins.Core/CodeInterpreter/SessionsPythonPlugin.cs:281
/// Sends an HTTP request to the specified path with the specified method and content.
/// </summary>
/// <param name="httpClient">The HTTP client to use.</param>
/// <param name="method">The HTTP method to use.</param>
/// <param name="path">The path to send the request to.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <param name="httpContent">The content to send with the request.</param>
/// <returns>The HTTP response message.</returns>
private async Task<HttpResponseMessage> SendAsync(HttpClient httpClient, HttpMethod method, string path, CancellationToken cancellationToken, HttpContent? httpContent = null)
{
// The query string is the same for all operations
var pathWithQueryString = $"{path}?identifier={this._settings.SessionId}&api-version={ApiVersion}";
var uri = new Uri(this._poolManagementEndpoint, pathWithQueryString);
// Deny requests unless the endpoint host is explicitly allowed.
if (this._settings.AllowedDomains?.Contains(uri.Host, StringComparer.OrdinalIgnoreCase) != true)
{
throw new InvalidOperationException(
$"Sending requests to host '{uri.Host}' is not allowed. Add the host to {nameof(SessionsPythonSettings.AllowedDomains)}.");
}
using var request = new HttpRequestMessage(method, uri)
{
Content = httpContent,
};
await this.AddHeadersAsync(request, cancellationToken).ConfigureAwait(false);
return await httpClient.SendWithSuccessCheckAsync(request, cancellationToken).ConfigureAwait(false);
}
/// <summary>
/// Validates that the local file path is within allowed upload directories.
/// </summary>
/// <param name="localFilePath">The local file path to validate.</param>
/// <returns>The canonicalized path if valid.</returns>View on GitHub (pinned to ca40aa7226)