microsoft/semantic-kernel · error · KernelException

No IExternalKernelProcessMessageChannel found, need at least

Error message

No IExternalKernelProcessMessageChannel found, need at least 1 to emit external messages

What it means

Thrown by LocalProxy.InitializeStepAsync when ExternalMessageChannel is null. A proxy step's purpose is to bridge process messages to an external system (e.g., a Dapr actor or another messaging infrastructure); without an IExternalKernelProcessMessageChannel it cannot emit external messages and initialization fails.

Source

Thrown at dotnet/src/Experimental/Process.LocalRuntime/LocalProxy.cs:75

        if (this._proxy.ProxyMetadata != null && message.SourceEventId != null && this._proxy.ProxyMetadata.EventMetadata.TryGetValue(message.SourceEventId, out var metadata) && metadata != null)
        {
            functionParameters![kvp.Key] = KernelProcessProxyMessageFactory.CreateProxyMessage(this.ParentProcessId!, message.SourceEventId, metadata.TopicName, kvp.Value);
        }
    }

    /// <inheritdoc/>
    protected override async ValueTask InitializeStepAsync()
    {
        if (this._isInitialized)
        {
            return;
        }

        // Ensure initialization happens only once if first time or again if "deinitialization" was called
        if (this.ExternalMessageChannel == null)
        {
            throw new KernelException("No IExternalKernelProcessMessageChannel found, need at least 1 to emit external messages");
        }

        await this.ExternalMessageChannel.Initialize().ConfigureAwait(false);
        await base.InitializeStepAsync().ConfigureAwait(false);
        this._isInitialized = true;
    }

    /// <summary>
    /// Deinitialization of the Proxy Step, calling <see cref="KernelProxyStep.DeactivateAsync(KernelProcessStepExternalContext)"/>
    /// </summary>
    /// <returns></returns>
    public override async Task DeinitializeStepAsync()
    {
        MethodInfo? derivedMethod = this._stepInfo.InnerStepType.GetMethod(
            nameof(KernelProxyStep.DeactivateAsync),
            BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance,
            binder: null,
            types: [typeof(KernelProcessStepExternalContext)],

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Provide an IExternalKernelProcessMessageChannel implementation when using KernelProcessProxy steps.
  2. If running in the local runtime, avoid KernelProcessProxy steps or supply a custom ExternalMessageChannel.
  3. If using the Dapr runtime, ensure the DaprKernelProcessContext wires the channel correctly.

Example fix

// before - proxy step with no external channel
var proxy = new KernelProcessProxy { ... };
process.AddStep(proxy);
// after - provide an external message channel
localProxy.ExternalMessageChannel = new MyExternalMessageChannel();
Defensive patterns

Strategy: validation

Validate before calling

// Before using a KernelProcessProxy, verify an external message channel is available
if (step is KernelProcessProxy && externalMessageChannel is null)
{
    throw new InvalidOperationException("KernelProcessProxy steps require an IExternalKernelProcessMessageChannel.");
}

Prevention

When it happens

Trigger: A KernelProcessProxy step is added to a process, but no ExternalMessageChannel is provided to the LocalProxy instance. The channel is typically injected when the proxy step is constructed within a process that supports external messaging.

Common situations: Using a KernelProcessProxy in the LocalProcess runtime (in-process) which does not provide an external message channel by default; forgetting to wire the ExternalMessageChannel when programmatically constructing the process; using proxy steps that require Dapr or another external runtime but running in local mode.

Related errors


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