microsoft/semantic-kernel · error · KernelException
External message channel not configured for step with topic
Error message
External message channel not configured for step with topic {processEventData.ExternalTopicName} What it means
Thrown by KernelProcessStepExternalContext.EmitExternalEventAsync when no IExternalKernelProcessMessageChannel was injected into the context. The context's _externalMessageChannel field is null because the constructor was called with a null channel argument (the default). The framework cannot route the event to an external bus (e.g., Service Bus, SignalR) without a configured channel.
Source
Thrown at dotnet/src/Experimental/Process.Abstractions/KernelProcessStepExternalContext.cs:34
/// </summary>
/// <param name="externalMessageChannel">An instance of <see cref="IExternalKernelProcessMessageChannel"/></param>
public KernelProcessStepExternalContext(IExternalKernelProcessMessageChannel? externalMessageChannel = null)
{
this._externalMessageChannel = externalMessageChannel;
}
/// <summary>
/// Emit an external event to through a <see cref="IExternalKernelProcessMessageChannel"/>
/// component if connected from within the SK process
/// </summary>
/// <param name="processEventData">data containing event details</param>
/// <returns></returns>
/// <exception cref="KernelException"></exception>
public async Task EmitExternalEventAsync(KernelProcessProxyMessage processEventData)
{
if (this._externalMessageChannel == null)
{
throw new KernelException($"External message channel not configured for step with topic {processEventData.ExternalTopicName}");
}
await this._externalMessageChannel.EmitExternalEventAsync(processEventData.ExternalTopicName, processEventData).ConfigureAwait(false);
}
/// <summary>
/// Closes connection with external messaging channel
/// </summary>
/// <returns><see cref="Task"/></returns>
/// <exception cref="KernelException"></exception>
public async Task CloseExternalEventChannelAsync()
{
if (this._externalMessageChannel == null)
{
throw new KernelException("External message channel not configured for step");
}
await this._externalMessageChannel.Uninitialize().ConfigureAwait(false);View on GitHub (pinned to c028a0c7dc)
Solutions
- Register an IExternalKernelProcessMessageChannel implementation with your process runtime so that KernelProcessStepExternalContext is constructed with a non-null channel.
- Verify that the proxy step added via ProcessBuilder.AddProxyStep is accompanied by a matching external channel registration in the kernel/process host configuration.
- If the step should not emit externally, remove the call to EmitExternalEventAsync or guard it by checking whether the external context has a configured channel before invoking.
- Check that the KernelProcess is started through the process runtime that injects external channels (e.g., KernelProcessFunctionExecution or the process runtime extension), not a bare step activation.
Example fix
// before var context = new KernelProcessStepExternalContext(); // no channel await context.EmitExternalEventAsync(message); // throws // after IExternalKernelProcessMessageChannel channel = new MyMessageChannel(); var context = new KernelProcessStepExternalContext(channel); await context.EmitExternalEventAsync(message);
Defensive patterns
Strategy: validation
Validate before calling
// Before emitting, check if the external context has a channel configured.
// Note: _externalMessageChannel is private; callers should track whether a channel
// was provided at construction time.
public bool HasExternalChannel(KernelProcessStepExternalContext ctx)
{
// No public API exposes this; you must track it at the process-host level.
// Ensure your IExternalKernelProcessMessageChannel is registered before process start.
return _externalChannelIsRegistered;
} Try / catch
try
{
await context.EmitExternalEventAsync(message);
}
catch (KernelException ex) when (ex.Message.Contains("External message channel not configured"))
{
_logger.LogWarning("External channel not configured; skipping external emit for topic {Topic}", message.ExternalTopicName);
} Prevention
- Register the IExternalKernelProcessMessageChannel implementation with your process runtime before calling KernelProcess.runAsync.
- Verify the channel is non-null in your process host setup code before starting any step that emits externally.
- Only add proxy steps (AddProxyStep) when an external channel is available.
When it happens
Trigger: A KernelProcessStepContext or KernelProcessStepExternalContext is created without passing an IExternalKernelProcessMessageChannel instance, and then EmitExternalEventAsync is called at runtime (typically from within a KernelProcessStep that tries to emit an event externally via the proxy step's external topic).
Common situations: Running a process that contains an AddProxyStep but the external message channel was not registered with the kernel or process runtime. Migrating from an older SK version where external channels were optional. Unit-testing a step in isolation without wiring up the external channel infrastructure. Forgetting to call kernelBuilder.WithExternalMessageChannel() (or equivalent setup) before starting the process.
Related errors
- External message channel not configured for step
- No IExternalKernelProcessMessageChannel found, need at least
- Configuration not found, please setup the notebooks first us
- AZURE_OPENAI_ENDPOINT is not set.
- AZURE_OPENAI_ENDPOINT is not set.
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/291640293fbbbd38.
Report an issue: GitHub.