microsoft/semantic-kernel · error · KernelException
The address '{address}' is not allowed for the '{operation.N
Error message
The address '{address}' is not allowed for the '{operation.Name}' gRPC operation. The address must match one of the allowed base addresses. What it means
Thrown when `_allowedAddresses` is configured (non-empty) and the resolved operation address does not prefix-match any allowed base address with a proper boundary (`/`, `?`, or `#` after the prefix). This is an SSRF guard: even with a valid scheme, the destination must fall under a whitelisted base.
Source
Thrown at dotnet/src/Functions/Functions.Grpc/GrpcOperationRunner.cs:215
{
// If the allowed URI already ends at a boundary (e.g., trailing '/'),
// or the full URIs match exactly, no further check is needed.
// Otherwise, ensure the next character is a path boundary to prevent
// prefix bypasses (e.g., allowed "https://host/grpc" should not match "https://host/grpcevil").
int prefixLength = allowedUri.Length;
if (prefixLength >= addressUri.AbsoluteUri.Length ||
allowedUri[prefixLength - 1] is '/' ||
addressUri.AbsoluteUri[prefixLength] is '/' or '?' or '#')
{
isAllowed = true;
break;
}
}
}
if (!isAllowed)
{
throw new KernelException($"The address '{address}' is not allowed for the '{operation.Name}' gRPC operation. The address must match one of the allowed base addresses.");
}
}
return address!;
}
/// <summary>
/// Creates a marshaller - a typed abstraction for gRPC message serialization and deserialization.
/// </summary>
/// <param name="contractType">The message contract data type.</param>
/// <returns>The marshaller.</returns>
private Marshaller<T> CreateMarshaller<T>(Type contractType)
{
byte[] Serialize(T instance)
{
using var memoryStream = new MemoryStream();
Serializer.NonGeneric.Serialize(memoryStream, instance);View on GitHub (pinned to c028a0c7dc)
Solutions
- Point the address at a URL that starts with (and is bounded by) an allowed base address.
- Add the service's base address to AllowedAddresses in GrpcOperationRunnerOptions.
- Ensure the allow-list entry ends with `/` if the base is a path prefix.
Example fix
// before
// allowed = [https://api.example.com/], address = https://api2.example.com/v1
// after
options.AllowedAddresses = new[] { new Uri("https://api2.example.com/") };
// or use an already-allowed host Defensive patterns
Strategy: validation
Validate before calling
bool allowed(Uri addr, IEnumerable<Uri> bases) =>
bases.Any(b => addr.AbsoluteUri.StartsWith(b.AbsoluteUri, StringComparison.OrdinalIgnoreCase)); Prevention
- Maintain an explicit, reviewed AllowedAddresses list.
- End base addresses with '/' when they are path prefixes.
When it happens
Trigger: Allowed base is `https://internal.example.com/` and the address is `https://internal.example.com.evil.com/` (no boundary) or `https://other.example.com/` (no match).
Common situations: Address override pointing outside the approved base; production allow-list missing the new service host after a migration; trailing-slash mismatch between allow-list entry and address.
Related errors
- The URI scheme '{addressUri.Scheme}' is not allowed for the
- No address provided for the '{operation.Name}' gRPC operatio
- The address '{address}' for the '{operation.Name}' gRPC oper
- No .proto document for the specified path - {filePath} is fo
- No '{GrpcOperation.PayloadArgumentName}' argument representi
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/b67e90a892c6ea3b.
Report an issue: GitHub.