LiteBus
CatalogDispatch

Outbox Kafka Dispatch

  • ID: dispatch.outbox.kafka
  • Name: Outbox Kafka dispatch
  • Maturity: GA
  • Summary: Publish leased outbox envelopes to Kafka topics with contract headers via UseKafkaDispatch.

What It Does

Registers TransportOutboxDispatchModule with KafkaTransportModule. Outbox processor produces records to the configured topic with key from topic metadata, resolver, or contract name. Payload and headers follow the same mapping as other transport outbox adapters.

Packages

PackageRole
LiteBus.Outbox.Dispatch.KafkaRegistration glue
LiteBus.Outbox.DispatchShared dispatcher
LiteBus.Transport.KafkaConfluent adapter

Requires

  • dispatch.transport-core
  • transport.kafka
  • durable-core.outbox

Invariants

  • Default hook failure policy: CompleteDespiteHookFailure.
  • At-least-once: consumers must deduplicate using headers or business logic.
  • No broker-level deduplication of republished outbox rows after processor crash.

Non-Goals

  • Does not use Kafka idempotent producer settings as outbox exactly-once guarantee.
  • Does not consume from topics.

Public Surface

services.AddLiteBus(litebus =>
{
    litebus.AddKafkaTransport(new KafkaTransportOptions
    {
        BootstrapServers = "localhost:9092",
        ClientId = "orders-outbox-dispatch"
    });

    litebus.AddOutbox(outbox =>
    {
        outbox.EnableOutboxProcessor();
        outbox.UseKafkaDispatch(
            options =>
            {
                options.DefaultDestination = "orders.events";
            });
    });
});
APIRole
OutboxModuleBuilder.UseKafkaDispatch(Action<TransportOutboxDispatcherOptions>)Registers outbox transport dispatcher that requires the root Kafka transport
TransportOutboxDispatchModule.DefaultHookFailurePolicyDefaults to CompleteDespiteHookFailure
TransportOutboxDispatcher.DispatchAsync(OutboxEnvelope, CancellationToken)Publishes outbox payload and headers to Kafka

Route resolution: tenant strategy, then envelope Topic, then resolver, then contract name.

Observability

SignalDetail
send {destination}Topic destination, messaging.kafka.message.key, and message id attributes
litebus.transport.circuit_breaker.open / failure_countTag litebus.transport.broker="kafka"
litebus.outbox.processor.published / failedTerminal outcomes after Kafka publish attempt
litebus.outbox.processor.dispatch_durationIncludes producer send latency

Failure paths increment circuit breaker when broker is unreachable (KafkaDispatchFailureIntegrationTests).

Deep Docs

Test Coverage

Covered

Test methodProject
OutboxDispatchExtensions_ShouldRegisterTransportDispatcherLiteBus.Durable.IntegrationTests (Registration/) (Kafka Theory case)
ProcessPendingAsync_ShouldPublishEnvelopeToKafkaTopicLiteBus.Durable.IntegrationTests (Dispatch/Outbox/Kafka/)
ProcessPendingAsync_WhenTopicMissing_ShouldUseContractNameAsRouteLiteBus.Durable.IntegrationTests (Dispatch/Outbox/Kafka/)
ProcessPendingAsync_WhenBrokerUnreachable_ShouldMarkFailedWithVisibleAfterLiteBus.Durable.IntegrationTests (Dispatch/Outbox/Kafka/)
ProcessPendingAsync_WhenCircuitBreakerOpen_ShouldNotPublishLiteBus.Durable.IntegrationTests (Dispatch/Outbox/Kafka/)

Untested

  • After-dispatch hook failure path with CompleteDespiteHookFailure.
  • Tenant route strategy branch and custom resolver branch.
  • Idempotent producer settings as an exactly-once guarantee, which is outside dispatch guarantees.

Out-of-Scope

  • Kafka idempotent producer as outbox exactly-once guarantee
  • Consuming from Kafka topics

On this page