Skip to main content

Compatibility

See the Kafka feature support matrix for KIP scope, broker capabilities, runtime limits, and validation evidence.

Dekaf's core and Abstractions packages target net10.0, net8.0, and netstandard2.0. The extension, serialization, compression, Schema Registry, and testing packages target net8.0 and net10.0; tools target net10.0.

The project is open to broader target-framework support when it does not regress the net10.0 performance path. netstandard2.0 support is tracked by #1224 and split into staged child issues so compatibility work can land without weakening the current package.

Current Support

AreaStatus
Core and Abstractions packagesnet10.0, net8.0, netstandard2.0
Compression packagesnet8.0, net10.0
Serialization packagesnet8.0, net10.0
Schema Registry packagesnet8.0, net10.0
Dependency Injection, Hosting, Health Checksnet8.0, net10.0
Testing packagenet8.0, net10.0
Tools, benchmarks, stress testsnet10.0

The net10.0 target stays the primary optimization target. Protocol serialization, production, and consumption hot paths should continue using modern BCL APIs where they are needed for low allocation and throughput.

.NET 8 package asset

.NET 8 applications select the dedicated net8.0 core and Abstractions assets. They retain the IReadOnlyCollection and serializer contracts previously selected through netstandard2.0, while enabling the existing managed GSSAPI implementation. The optimized net10.0 asset retains its IReadOnlySet, ref-struct, and static protocol dispatch paths. No additional authentication package is required.

GSSAPI uses Windows SSPI, Linux Kerberos libraries and credentials, or macOS Heimdal. CI exercises a local MIT KDC and authenticated admin/produce/consume round trips for clean .NET 8 and .NET 10 NuGet consumers on Linux, including rejection of an invalid service identity. Windows and macOS coverage is based on the implementation; these Kerberos round trips do not certify those platforms. Windows explicit KeytabPath remains unsupported; use the Windows credential store or run under the desired service identity. See SASL authentication.

The netstandard2.0 asset still throws PlatformNotSupportedException for GSSAPI. The .NET 8 asset retains reflection-based protocol metadata and does not declare trim/Native AOT compatibility. Use the .NET 10 asset for supported AOT scenarios.

netstandard2.0 Goal

The compatibility goal is to let older applications consume Dekaf packages without requiring a second Kafka client package, while preserving the existing net10.0 behavior and performance.

The intended path is staged:

  1. Define the compatibility plan and blocker categories (#1298).
  2. Establish a core netstandard2.0 restore/build baseline (#1299).
  3. Replace, guard, or polyfill core net10.0 API blockers (#1300).
  4. Add package and smoke validation for the final supported package set (#1301).

Build Probe

The first compatibility probe forced the core package to compile as netstandard2.0 without editing project files:

dotnet build src/Dekaf/Dekaf.csproj --configuration Release `
-p:TargetFrameworks=netstandard2.0 `
-p:TargetFramework=netstandard2.0

That probe confirmed the work is cross-cutting and should not be shipped as one large PR.

netstandard2.0 Restore Baseline

The #1299 baseline keeps Dekaf defaulting to net10.0, but adds the conditional project structure needed for an explicit netstandard2.0 probe:

  • System.IO.Pipelines, System.Threading.Channels, and System.Text.Json package references are included only when $(TargetFramework) is netstandard2.0.
  • Modern compiler-support shims are included only for netstandard2.0, including IsExternalInit, required-member attributes, nullable flow annotation support, and SkipLocalsInitAttribute.
  • The forced probe now restores successfully and gets past the missing package-reference and required-member compiler-support errors.

Run the current probe with:

dotnet build src/Dekaf/Dekaf.csproj --configuration Release `
-p:TargetFrameworks=netstandard2.0 `
-p:TargetFramework=netstandard2.0

The #1300 pass removes the core compile blocker layer. The forced probe now builds cleanly:

dotnet build src/Dekaf/Dekaf.csproj --configuration Release `
-p:TargetFrameworks=netstandard2.0 `
-p:TargetFramework=netstandard2.0

This pass includes:

  • CRC32C hardware intrinsics are guarded so netstandard2.0 uses the existing software CRC path.
  • IReadOnlySet<T> public and internal surfaces are target-aliased to IReadOnlyCollection<T> for netstandard2.0.
  • System.Threading.Lock, PeriodicTimer, non-generic TaskCompletionSource, Task.WaitAsync, CancellationTokenSource.CancelAsync, ArrayBufferWriter<T>, SequenceReader<T>, Index, Range, HashCode, ValueTask.CompletedTask, and related BCL helpers have conditional compatibility shims.
  • Span-based compression stream APIs use array-based stream calls on netstandard2.0.
  • Generic protocol send/read paths no longer require static abstract interface members for netstandard2.0; net10.0 keeps static interface dispatch through the metadata helper.
  • TLS authentication uses the older SslStream.AuthenticateAsClientAsync overload on netstandard2.0.
  • GSSAPI remains part of the API surface, but using it on netstandard2.0 throws PlatformNotSupportedException because NegotiateAuthentication is unavailable there.

The #1301 package pass declares netstandard2.0 support for the core Dekaf package only. CI packs the package with both lib/net10.0/Dekaf.dll and lib/netstandard2.0/Dekaf.dll, then restores a sample netstandard2.0 library from the local .nupkg and runs it through a net10.0 console host.

Blocker Categories

Missing Package References

Several APIs are inbox for net10.0 but require package references or replacement when targeting netstandard2.0:

  • System.IO.Pipelines
  • System.Threading.Channels
  • System.Text.Json
  • System.Runtime.Intrinsics
  • hashing and runtime support packages used by core protocol paths

The first build child should add conditional package references only for targets that need them, leaving net10.0 package closure unchanged where possible.

Compiler Support Shims

The codebase uses modern C# features such as init and required. A netstandard2.0 target needs compatibility definitions for compiler support types such as:

  • System.Runtime.CompilerServices.IsExternalInit
  • System.Runtime.CompilerServices.RequiredMemberAttribute
  • System.Runtime.CompilerServices.CompilerFeatureRequiredAttribute
  • System.Diagnostics.CodeAnalysis.SetsRequiredMembersAttribute

These shims should be internal, conditional, and included only for older target frameworks.

net10-only API Usage

Some source paths use APIs that do not exist on netstandard2.0:

  • span-based stream overrides such as Stream.Write(ReadOnlySpan<byte>)
  • System.Threading.Lock
  • Task.WaitAsync
  • modern throw helpers
  • selected runtime intrinsics and vectorized helpers

Each replacement needs performance review. The net10.0 hot path should keep modern APIs when conditional compilation can isolate the compatibility path.

Package Matrix

Not every package has to multi-target at the same time. The current sequence is:

  1. Dekaf and Dekaf.Abstractions - shipped as net10.0, net8.0, and netstandard2.0
  2. serialization and compression packages that can compile without framework-specific hosting dependencies
  3. Schema Registry packages
  4. extensions packages where their Microsoft.Extensions.* dependencies support the chosen older target
  5. Dekaf.Testing

Tools, benchmarks, stress tests, and CI utilities should remain net10.0.

Validation Requirements

Compatibility support is not complete until these checks exist:

  • dotnet build for net10.0 remains green.
  • Packable libraries build for every declared target framework.
  • A sample or smoke test references the netstandard2.0 asset from a supported runtime.
  • Unit tests continue running against net10.0.
  • Any compatibility helper has focused tests or compile canaries.

Integration tests should keep using the existing runtime target unless a specific compatibility runtime issue requires a separate run.

Run the package smoke locally after packing:

./scripts/RunNetStandardPackageSmoke.ps1

Non-goals

  • Do not lower the runtime target for tools, benchmarks, or stress tests.
  • Do not replace high-performance net10.0 code with slower shared code when conditional compilation can keep the fast path.
  • Do not claim netstandard2.0 support until package restore, build, packaging, and smoke validation are all in place.