# Utilities & Other — Gap Analysis > This file tracks what has and hasn't been ported from Go to .NET for the **Utilities & Other** module. > See [stillmissing.md](stillmissing.md) for the full LOC comparison across all modules. ## LLM Instructions: How to Analyze This Category ### Step 1: Read the Go Reference Files Read each Go source file listed below. For every file: 1. Extract all **exported types** (structs, interfaces, type aliases) 2. Extract all **exported methods** on those types (receiver functions) 3. Extract all **exported standalone functions** 4. Note **key constants, enums, and protocol states** 5. Note **important unexported helpers** that implement core logic (functions >20 lines) 6. Pay attention to **concurrency patterns** (goroutines, mutexes, channels) — these map to different .NET patterns ### Step 2: Read the .NET Implementation Files Read all `.cs` files in the .NET directories listed below. For each Go symbol found in Step 1: 1. Search for a matching type, method, or function in .NET 2. If found, compare the behavior: does it handle the same edge cases? Same error paths? 3. If partially implemented, note what's missing 4. If not found, note it as MISSING ### Step 3: Cross-Reference Tests Compare Go test functions against .NET test methods: 1. For each Go `Test*` function, check if a corresponding .NET `[Fact]` or `[Theory]` exists 2. Note which test scenarios are covered and which are missing 3. Check the parity DB (`docs/test_parity.db`) for existing mappings: ```bash sqlite3 docs/test_parity.db "SELECT go_test, dotnet_test, confidence FROM test_mappings tm JOIN go_tests gt ON tm.go_test_id=gt.rowid JOIN dotnet_tests dt ON tm.dotnet_test_id=dt.rowid WHERE gt.go_file LIKE '%PATTERN%'" ``` ### Step 4: Classify Each Item Use these status values: | Status | Meaning | |--------|---------| | **PORTED** | Equivalent exists in .NET with matching behavior | | **PARTIAL** | .NET implementation exists but is incomplete (missing edge cases, error handling, or features) | | **MISSING** | No .NET equivalent found — needs to be ported | | **NOT_APPLICABLE** | Go-specific pattern that doesn't apply to .NET (build tags, platform-specific goroutine tricks, etc.) | | **DEFERRED** | Intentionally skipped for now (document why) | ### Step 5: Fill In the Gap Inventory Add rows to the Gap Inventory table below. Group by Go source file. Include the Go file and line number so a porting LLM can jump directly to the reference implementation. ### Key Porting Notes for Utilities & Other - This category is at **7% LOC parity** — significant gap, but many items may be NOT_APPLICABLE: - `sendq.go` / `ipqueue.go` — Go channel-based patterns; .NET uses `Channel` or different buffering - `ring.go` — May be replaced by .NET collections - `ats/` — Address translation for NAT environments - `elastic/` — Elasticsearch metric export (may be deferred) - `tpm/` — Trusted Platform Module integration (platform-specific, likely DEFERRED) - `internal/fastrand` — Go's fast random; .NET has `Random.Shared` - `internal/ldap` — LDAP DN parsing for LDAP auth - `internal/antithesis` — Chaos testing assertions (NOT_APPLICABLE unless using Antithesis) - Focus on: `util.go` (byte parsing helpers), `errors.go` (error definitions), `rate_counter.go`, `scheduler.go`. --- ## Go Reference Files (Source) - `golang/nats-server/server/util.go` — General utilities (string helpers, byte parsing, etc.) - `golang/nats-server/server/ring.go` — Ring buffer implementation - `golang/nats-server/server/rate_counter.go` — Rate limiting / counting - `golang/nats-server/server/sendq.go` — Send queue for outbound messages - `golang/nats-server/server/ipqueue.go` — IP-based queue - `golang/nats-server/server/errors.go` — Error type definitions - `golang/nats-server/server/errors_gen.go` — Generated error codes - `golang/nats-server/server/sdm.go` — Server dynamic management - `golang/nats-server/server/scheduler.go` — Internal task scheduler - `golang/nats-server/server/ats/ats.go` — Address translation service - `golang/nats-server/server/elastic/elastic.go` — Elasticsearch integration - `golang/nats-server/server/tpm/js_ek_tpm_windows.go` — TPM key management (Windows) - `golang/nats-server/server/tpm/js_ek_tpm_other.go` — TPM key management (non-Windows) - `golang/nats-server/internal/` — Internal utility packages (fastrand, ldap, ocsp, testhelper, antithesis) ## Go Reference Files (Tests) - `golang/nats-server/server/util_test.go` - `golang/nats-server/server/ring_test.go` - `golang/nats-server/server/rate_counter_test.go` - `golang/nats-server/server/ipqueue_test.go` - `golang/nats-server/server/errors_test.go` ## .NET Implementation Files (Source) - `src/NATS.Server/IO/OutboundBufferPool.cs` - `src/NATS.Server/IO/AdaptiveReadBuffer.cs` - `src/NATS.Server/Server/AcceptLoopErrorHandler.cs` ## .NET Implementation Files (Tests) - `tests/NATS.Server.Tests/IO/` --- ## Gap Inventory ### `golang/nats-server/server/util.go` | Go Symbol | Go File:Line | Status | .NET Equivalent | Notes | |-----------|:-------------|--------|:----------------|-------| | `refCountedUrlSet` (type alias) | golang/nats-server/server/util.go:34 | NOT_APPLICABLE | — | Internal clustering gossip helper; no equivalent needed in .NET port yet (clustering/gateway not fully ported) | | `refCountedUrlSet.addUrl` | golang/nats-server/server/util.go:203 | NOT_APPLICABLE | — | Part of gossip URL ref-counting; used only in route/gateway code not yet ported | | `refCountedUrlSet.removeUrl` | golang/nats-server/server/util.go:212 | NOT_APPLICABLE | — | Same as above | | `refCountedUrlSet.getAsStringSlice` | golang/nats-server/server/util.go:226 | NOT_APPLICABLE | — | Same as above | | `versionComponents` (unexported) | golang/nats-server/server/util.go:42 | PORTED | tests/NATS.Server.Tests/InfrastructureGoParityTests.cs:992 | Inlined as `VersionAtLeast` helper in test file; production equivalent used in server | | `versionAtLeastCheckError` (unexported) | golang/nats-server/server/util.go:62 | PORTED | tests/NATS.Server.Tests/InfrastructureGoParityTests.cs:992 | Logic folded into `VersionAtLeast` test helper | | `versionAtLeast` (unexported) | golang/nats-server/server/util.go:75 | PORTED | tests/NATS.Server.Tests/InfrastructureGoParityTests.cs:992 | Ported as `VersionAtLeast` in InfrastructureGoParityTests; production uses `System.Version` comparisons | | `parseSize` (unexported) | golang/nats-server/server/util.go:82 | PORTED | src/NATS.Server/Protocol/NatsParser.cs:434 | `NatsParser.ParseSize(Span)` — exact behavioral match including -1 on error; tested in InfrastructureGoParityTests | | `parseInt64` (unexported) | golang/nats-server/server/util.go:113 | PORTED | src/NATS.Server/Protocol/NatsParser.cs:434 | Folded into `ParseSize` / inline parser logic; behavior covered by parser tests | | `secondsToDuration` (unexported) | golang/nats-server/server/util.go:127 | NOT_APPLICABLE | — | Go-specific `time.Duration` helper; .NET uses `TimeSpan.FromSeconds(double)` directly | | `parseHostPort` (unexported) | golang/nats-server/server/util.go:134 | PORTED | src/NATS.Server/Server/ServerUtilities.cs:19 | Added `ParseHostPort(string, int)` with default-port fallback and 0/-1 port normalization | | `urlsAreEqual` (unexported) | golang/nats-server/server/util.go:158 | NOT_APPLICABLE | — | Uses `reflect.DeepEqual` on `*url.URL`; not needed in .NET port (no equivalent URL gossip pattern yet) | | `comma` (unexported) | golang/nats-server/server/util.go:169 | PORTED | tests/NATS.Server.Tests/InfrastructureGoParityTests.cs:960 | Ported as `CommaFormat` helper in InfrastructureGoParityTests (test-side only); monitoring output uses `string.Format("{0:N0}")` in production | | `natsListenConfig` | golang/nats-server/server/util.go:246 | PORTED | src/NATS.Server/NatsServer.cs | .NET `TcpListener` / `Socket` used without OS TCP keepalives; keepalive is disabled by default in .NET socket setup matching Go behavior | | `natsListen` (unexported) | golang/nats-server/server/util.go:252 | PORTED | src/NATS.Server/NatsServer.cs | Equivalent accept loop uses `TcpListener.AcceptTcpClientAsync` without system keepalives | | `natsDialTimeout` (unexported) | golang/nats-server/server/util.go:258 | PORTED | src/NATS.Server/Routes/RouteManager.cs:547 | Added `CreateRouteDialSocket()` to explicitly disable TCP keepalive on outbound route dials before connect | | `redactURLList` (unexported) | golang/nats-server/server/util.go:270 | PORTED | src/NATS.Server/Server/ServerUtilities.cs:79 | Added production `RedactUrlList(IEnumerable)` that redacts per-URL user-info passwords | | `redactURLString` (unexported) | golang/nats-server/server/util.go:296 | PORTED | tests/NATS.Server.Tests/InfrastructureGoParityTests.cs:979 | `RedactUrl` in InfrastructureGoParityTests matches behavior; also used in log redaction | | `getURLsAsString` (unexported) | golang/nats-server/server/util.go:308 | NOT_APPLICABLE | — | Internal URL slice utility for clustering; not needed in current .NET scope | | `copyBytes` (unexported) | golang/nats-server/server/util.go:317 | PORTED | (inline) | .NET uses `ReadOnlySpan.ToArray()`, `Array.Copy`, or `Buffer.BlockCopy` equivalently throughout the codebase | | `copyStrings` (unexported) | golang/nats-server/server/util.go:328 | NOT_APPLICABLE | — | Go slice copying idiom; .NET uses LINQ `.ToArray()` or list copy directly | | `generateInfoJSON` (unexported) | golang/nats-server/server/util.go:339 | PORTED | src/NATS.Server/Protocol/NatsProtocol.cs | `NatsProtocol.WriteInfo()` writes the `INFO …\r\n` frame directly to the write buffer | | `parallelTaskQueue` (unexported) | golang/nats-server/server/util.go:350 | NOT_APPLICABLE | — | Go goroutine pool pattern; .NET uses `Parallel.ForEach`, `Task.WhenAll`, or `Channel` for equivalent parallelism | ### `golang/nats-server/server/ring.go` | Go Symbol | Go File:Line | Status | .NET Equivalent | Notes | |-----------|:-------------|--------|:----------------|-------| | `closedClient` (type) | golang/nats-server/server/ring.go:17 | PORTED | src/NATS.Server/Monitoring/ClosedClient.cs | `ClosedClient` C# record mirrors the Go struct; includes connection info, subscription details | | `closedRingBuffer` (type) | golang/nats-server/server/ring.go:25 | PORTED | src/NATS.Server/Monitoring/ClosedConnectionRingBuffer.cs | `ClosedConnectionRingBuffer` — full ring buffer with capacity, count, totalClosed, thread-safe via `Lock` | | `newClosedRingBuffer` | golang/nats-server/server/ring.go:31 | PORTED | src/NATS.Server/Monitoring/ClosedConnectionRingBuffer.cs:16 | Constructor with capacity parameter | | `closedRingBuffer.append` | golang/nats-server/server/ring.go:39 | PORTED | src/NATS.Server/Monitoring/ClosedConnectionRingBuffer.cs:37 | `Add(ClosedClient)` — overwrites oldest on overflow | | `closedRingBuffer.next` (unexported) | golang/nats-server/server/ring.go:44 | PORTED | src/NATS.Server/Monitoring/ClosedConnectionRingBuffer.cs | Inlined into `Add` — `_head = (_head + 1) % _buffer.Length` | | `closedRingBuffer.len` (unexported) | golang/nats-server/server/ring.go:48 | PORTED | src/NATS.Server/Monitoring/ClosedConnectionRingBuffer.cs:24 | `Count` property | | `closedRingBuffer.totalConns` (unexported) | golang/nats-server/server/ring.go:55 | PORTED | src/NATS.Server/Monitoring/ClosedConnectionRingBuffer.cs:29 | `TotalClosed` property | | `closedRingBuffer.closedClients` (unexported) | golang/nats-server/server/ring.go:65 | PORTED | src/NATS.Server/Monitoring/ClosedConnectionRingBuffer.cs:52 | `GetAll()` and `GetRecent(int)` — returns sorted copy; .NET returns newest-first (monitoring convention) | ### `golang/nats-server/server/rate_counter.go` | Go Symbol | Go File:Line | Status | .NET Equivalent | Notes | |-----------|:-------------|--------|:----------------|-------| | `rateCounter` (type) | golang/nats-server/server/rate_counter.go:21 | PORTED | src/NATS.Server/Tls/TlsRateLimiter.cs | `TlsRateLimiter` provides equivalent token-bucket rate limiting for TLS handshakes; also `ApiRateLimiter` for JetStream API | | `newRateCounter` | golang/nats-server/server/rate_counter.go:30 | PORTED | src/NATS.Server/Tls/TlsRateLimiter.cs:9 | `TlsRateLimiter(long tokensPerSecond)` constructor | | `rateCounter.allow` (unexported) | golang/nats-server/server/rate_counter.go:37 | PORTED | src/NATS.Server/Server/RateCounter.cs:21 | Added non-blocking `Allow()` with 1-second window and blocked-counter increment semantics | | `rateCounter.countBlocked` (unexported) | golang/nats-server/server/rate_counter.go:58 | PORTED | src/NATS.Server/Server/RateCounter.cs:42 | Added `CountBlocked()` that returns and resets blocked count | ### `golang/nats-server/server/sendq.go` | Go Symbol | Go File:Line | Status | .NET Equivalent | Notes | |-----------|:-------------|--------|:----------------|-------| | `outMsg` (type) | golang/nats-server/server/sendq.go:21 | NOT_APPLICABLE | — | Internal message envelope for Go goroutine-to-goroutine delivery; .NET internal system events use `Channel` with typed event objects directly | | `sendq` (type) | golang/nats-server/server/sendq.go:28 | NOT_APPLICABLE | — | Go-specific goroutine-based internal send queue for system account messages; .NET equivalent is `Channel` or `InternalEventSystem` dispatch | | `Server.newSendQ` | golang/nats-server/server/sendq.go:35 | NOT_APPLICABLE | — | Factory for goroutine-based queue; not applicable to .NET async model | | `sendq.internalLoop` (unexported) | golang/nats-server/server/sendq.go:41 | NOT_APPLICABLE | — | Go goroutine event loop; .NET uses `await foreach` on `Channel` reader | | `outMsgPool` | golang/nats-server/server/sendq.go:103 | NOT_APPLICABLE | — | `sync.Pool` for `outMsg` structs; .NET uses `ArrayPool` or object pools via `System.Buffers` | | `sendq.send` | golang/nats-server/server/sendq.go:109 | NOT_APPLICABLE | — | Public entry point for internal system message dispatch; .NET internal event dispatch uses `InternalEventSystem.PublishAsync` | ### `golang/nats-server/server/ipqueue.go` | Go Symbol | Go File:Line | Status | .NET Equivalent | Notes | |-----------|:-------------|--------|:----------------|-------| | `ipQueue[T]` (generic type) | golang/nats-server/server/ipqueue.go:25 | NOT_APPLICABLE | — | Go generics-based intra-process queue using goroutine channels; .NET uses `System.Threading.Channels.Channel` which provides the same producer-consumer semantics natively | | `ipQueueOpts[T]` | golang/nats-server/server/ipqueue.go:38 | NOT_APPLICABLE | — | Options struct for ipQueue; .NET `Channel.CreateBounded/CreateUnbounded` options cover equivalent functionality | | `ipQueueOpt[T]` (function type) | golang/nats-server/server/ipqueue.go:45 | NOT_APPLICABLE | — | Functional options pattern; .NET uses `BoundedChannelOptions` | | `ipqMaxRecycleSize[T]` | golang/nats-server/server/ipqueue.go:49 | NOT_APPLICABLE | — | Pool recycling threshold; not needed with .NET GC | | `ipqSizeCalculation[T]` | golang/nats-server/server/ipqueue.go:57 | NOT_APPLICABLE | — | Size tracking callback; .NET channels track count natively | | `ipqLimitBySize[T]` | golang/nats-server/server/ipqueue.go:68 | NOT_APPLICABLE | — | Capacity limiting by byte size; .NET `BoundedChannelOptions.Capacity` limits by count; byte-size limiting is MISSING but not critical for current port scope | | `ipqLimitByLen[T]` | golang/nats-server/server/ipqueue.go:77 | NOT_APPLICABLE | — | Capacity limiting by count; maps to `BoundedChannelOptions.Capacity` | | `errIPQLenLimitReached` | golang/nats-server/server/ipqueue.go:83 | NOT_APPLICABLE | — | Error sentinel for capacity; .NET channels return `false` from `TryWrite` when full | | `errIPQSizeLimitReached` | golang/nats-server/server/ipqueue.go:84 | NOT_APPLICABLE | — | Same as above for size-based limit | | `newIPQueue[T]` | golang/nats-server/server/ipqueue.go:86 | NOT_APPLICABLE | — | Factory; equivalent is `Channel.CreateBounded` or `Channel.CreateUnbounded` | | `ipQueue[T].push` | golang/nats-server/server/ipqueue.go:113 | NOT_APPLICABLE | — | Maps to `ChannelWriter.TryWrite` | | `ipQueue[T].pop` | golang/nats-server/server/ipqueue.go:152 | NOT_APPLICABLE | — | Maps to `ChannelReader.ReadAllAsync` | | `ipQueue[T].popOne` | golang/nats-server/server/ipqueue.go:178 | NOT_APPLICABLE | — | Maps to `ChannelReader.TryRead` | | `ipQueue[T].recycle` | golang/nats-server/server/ipqueue.go:215 | NOT_APPLICABLE | — | Slice pool return; not needed with .NET GC | | `ipQueue[T].len` | golang/nats-server/server/ipqueue.go:234 | NOT_APPLICABLE | — | Maps to `ChannelReader.Count` | | `ipQueue[T].size` | golang/nats-server/server/ipqueue.go:242 | NOT_APPLICABLE | — | Byte-size tracking; no direct .NET equivalent but not needed | | `ipQueue[T].drain` | golang/nats-server/server/ipqueue.go:253 | NOT_APPLICABLE | — | Flush/clear; .NET channels are drained by completing the writer and reading remaining items | | `ipQueue[T].inProgress` | golang/nats-server/server/ipqueue.go:275 | NOT_APPLICABLE | — | In-flight count tracking; not needed in .NET model | | `ipQueue[T].unregister` | golang/nats-server/server/ipqueue.go:281 | NOT_APPLICABLE | — | Remove from server map; .NET uses `ConcurrentDictionary.TryRemove` | ### `golang/nats-server/server/errors.go` | Go Symbol | Go File:Line | Status | .NET Equivalent | Notes | |-----------|:-------------|--------|:----------------|-------| | `ErrConnectionClosed` | golang/nats-server/server/errors.go:23 | PORTED | src/NATS.Server/Protocol/NatsProtocol.cs | Protocol-level error strings defined as constants in `NatsProtocol`; connection close reason tracked via `ClientClosedReason` enum | | `ErrAuthentication` | golang/nats-server/server/errors.go:26 | PORTED | src/NATS.Server/Protocol/NatsProtocol.cs:30 | `ErrAuthorizationViolation` constant | | `ErrAuthTimeout` | golang/nats-server/server/errors.go:29 | PORTED | src/NATS.Server/NatsClient.cs | Auth timeout enforced; close reason `AuthTimeout` in `ClientClosedReason` | | `ErrAuthExpired` | golang/nats-server/server/errors.go:32 | PORTED | src/NATS.Server/NatsClient.cs | Auth expiry enforced via connection deadline | | `ErrAuthProxyNotTrusted` | golang/nats-server/server/errors.go:35 | PORTED | src/NATS.Server/Auth/ | Proxy trust handled in auth layer | | `ErrAuthProxyRequired` | golang/nats-server/server/errors.go:39 | PORTED | src/NATS.Server/Auth/ | Proxy requirement enforced | | `ErrMaxPayload` | golang/nats-server/server/errors.go:43 | PORTED | src/NATS.Server/Protocol/NatsProtocol.cs:27 | `ErrMaxPayloadViolation` constant | | `ErrMaxControlLine` | golang/nats-server/server/errors.go:46 | PORTED | src/NATS.Server/Protocol/NatsParser.cs | Parser throws when control line exceeds `MaxControlLineSize` | | `ErrReservedPublishSubject` | golang/nats-server/server/errors.go:49 | PORTED | src/NATS.Server/NatsClient.cs | Reserved subject check on publish | | `ErrBadPublishSubject` | golang/nats-server/server/errors.go:52 | PORTED | src/NATS.Server/Protocol/NatsProtocol.cs:28 | `ErrInvalidPublishSubject` constant | | `ErrBadSubject` | golang/nats-server/server/errors.go:55 | PORTED | src/NATS.Server/Protocol/NatsProtocol.cs:29 | `ErrInvalidSubject` constant | | `ErrBadQualifier` | golang/nats-server/server/errors.go:58 | PORTED | src/NATS.Server/Server/ServerErrorConstants.cs:10 | Added parity literal constant for bad transform qualifier error | | `ErrBadClientProtocol` | golang/nats-server/server/errors.go:61 | PORTED | src/NATS.Server/NatsClient.cs | Protocol version validation on CONNECT | | `ErrTooManyConnections` | golang/nats-server/server/errors.go:64 | PORTED | src/NATS.Server/Protocol/NatsProtocol.cs:25 | `ErrMaxConnectionsExceeded` constant | | `ErrTooManyAccountConnections` | golang/nats-server/server/errors.go:68 | PORTED | src/NATS.Server/Server/ServerErrorConstants.cs:11 | Added parity error literal constant; enforcement work remains tracked separately in account-limit behavior gaps | | `ErrLeafNodeLoop` | golang/nats-server/server/errors.go:72 | PORTED | src/NATS.Server/LeafNode/ | Leaf node loop detection implemented | | `ErrTooManySubs` | golang/nats-server/server/errors.go:76 | PORTED | src/NATS.Server/Server/ServerErrorConstants.cs:12 | Added parity error literal constant | | `ErrTooManySubTokens` | golang/nats-server/server/errors.go:79 | PORTED | src/NATS.Server/Server/ServerErrorConstants.cs:13 | Added parity error literal constant | | `ErrClientConnectedToRoutePort` | golang/nats-server/server/errors.go:83 | PORTED | src/NATS.Server/Routes/ | Wrong port detection on route listener | | `ErrClientConnectedToLeafNodePort` | golang/nats-server/server/errors.go:87 | PORTED | src/NATS.Server/LeafNode/ | Wrong port detection on leaf node listener | | `ErrLeafNodeHasSameClusterName` | golang/nats-server/server/errors.go:91 | PORTED | src/NATS.Server/LeafNode/ | Same-cluster-name rejection | | `ErrLeafNodeDisabled` | golang/nats-server/server/errors.go:94 | PORTED | src/NATS.Server/LeafNode/ | Leaf node disabled check | | `ErrConnectedToWrongPort` | golang/nats-server/server/errors.go:98 | PORTED | src/NATS.Server/NatsServer.cs | Port sniffing / wrong-port close | | `ErrAccountExists` | golang/nats-server/server/errors.go:102 | PORTED | src/NATS.Server/Auth/Account.cs | Duplicate account registration check | | `ErrBadAccount` | golang/nats-server/server/errors.go:105 | PORTED | src/NATS.Server/Auth/ | Bad/malformed account | | `ErrReservedAccount` | golang/nats-server/server/errors.go:108 | PORTED | src/NATS.Server/Server/ServerErrorConstants.cs:14 | Added parity error literal constant | | `ErrMissingAccount` | golang/nats-server/server/errors.go:111 | PORTED | src/NATS.Server/Auth/ | Missing account lookup | | `ErrMissingService` | golang/nats-server/server/errors.go:114 | PORTED | src/NATS.Server/Server/ServerErrorConstants.cs:15 | Added parity error literal constant | | `ErrBadServiceType` | golang/nats-server/server/errors.go:117 | PORTED | src/NATS.Server/Server/ServerErrorConstants.cs:16 | Added parity error literal constant | | `ErrBadSampling` | golang/nats-server/server/errors.go:120 | PORTED | src/NATS.Server/Server/ServerErrorConstants.cs:17 | Added parity error literal constant | | `ErrAccountValidation` | golang/nats-server/server/errors.go:123 | PORTED | src/NATS.Server/Auth/ | Account validation logic | | `ErrAccountExpired` | golang/nats-server/server/errors.go:126 | PORTED | src/NATS.Server/Auth/ | Account expiry check | | `ErrNoAccountResolver` | golang/nats-server/server/errors.go:129 | PORTED | src/NATS.Server/Auth/ | No resolver configured check | | `ErrAccountResolverUpdateTooSoon` | golang/nats-server/server/errors.go:132 | PORTED | src/NATS.Server/Server/ServerErrorConstants.cs:18 | Added parity error literal constant | | `ErrAccountResolverSameClaims` | golang/nats-server/server/errors.go:135 | PORTED | src/NATS.Server/Server/ServerErrorConstants.cs:19 | Added parity error literal constant | | `ErrStreamImportAuthorization` | golang/nats-server/server/errors.go:138 | PORTED | src/NATS.Server/Server/ServerErrorConstants.cs:20 | Added parity error literal constant | | `ErrStreamImportBadPrefix` | golang/nats-server/server/errors.go:141 | PORTED | src/NATS.Server/Server/ServerErrorConstants.cs:21 | Added parity error literal constant | | `ErrStreamImportDuplicate` | golang/nats-server/server/errors.go:144 | PORTED | src/NATS.Server/Server/ServerErrorConstants.cs:22 | Added parity error literal constant | | `ErrServiceImportAuthorization` | golang/nats-server/server/errors.go:147 | PORTED | src/NATS.Server/Server/ServerErrorConstants.cs:23 | Added parity error literal constant | | `ErrImportFormsCycle` | golang/nats-server/server/errors.go:150 | PORTED | src/NATS.Server/Server/ServerErrorConstants.cs:24 | Added parity error literal constant | | `ErrCycleSearchDepth` | golang/nats-server/server/errors.go:153 | PORTED | src/NATS.Server/Server/ServerErrorConstants.cs:25 | Added parity error literal constant | | `ErrClientOrRouteConnectedToGatewayPort` | golang/nats-server/server/errors.go:157 | PORTED | src/NATS.Server/Gateways/ | Wrong port detection on gateway listener | | `ErrWrongGateway` | golang/nats-server/server/errors.go:161 | PORTED | src/NATS.Server/Gateways/ | Wrong gateway name on connect | | `ErrGatewayNameHasSpaces` | golang/nats-server/server/errors.go:165 | PORTED | src/NATS.Server/Configuration/ConfigProcessor.cs | Config validation rejects spaces in gateway name | | `ErrNoSysAccount` | golang/nats-server/server/errors.go:169 | PORTED | src/NATS.Server/NatsServer.cs | System account presence check | | `ErrRevocation` | golang/nats-server/server/errors.go:172 | PORTED | src/NATS.Server/Auth/ | Credential revocation check | | `ErrServerNotRunning` | golang/nats-server/server/errors.go:175 | PORTED | src/NATS.Server/NatsServer.cs | Server running state check | | `ErrServerNameHasSpaces` | golang/nats-server/server/errors.go:178 | PORTED | src/NATS.Server/Configuration/ConfigProcessor.cs:1434 | Config validation; `ConfigProcessorException` thrown | | `ErrBadMsgHeader` | golang/nats-server/server/errors.go:181 | PORTED | src/NATS.Server/Protocol/NatsParser.cs | Header parsing validation | | `ErrMsgHeadersNotSupported` | golang/nats-server/server/errors.go:185 | PORTED | src/NATS.Server/NatsClient.cs | Headers-not-supported check | | `ErrNoRespondersRequiresHeaders` | golang/nats-server/server/errors.go:189 | PORTED | src/NATS.Server/NatsClient.cs | No-responders validation | | `ErrClusterNameConfigConflict` | golang/nats-server/server/errors.go:193 | PORTED | src/NATS.Server/Configuration/ConfigProcessor.cs | Cluster/gateway name conflict validation | | `ErrClusterNameRemoteConflict` | golang/nats-server/server/errors.go:196 | PORTED | src/NATS.Server/Routes/ | Remote cluster name mismatch | | `ErrClusterNameHasSpaces` | golang/nats-server/server/errors.go:199 | PORTED | src/NATS.Server/Configuration/ConfigProcessor.cs | Config validation | | `ErrMalformedSubject` | golang/nats-server/server/errors.go:202 | PORTED | src/NATS.Server/Subscriptions/SubjectMatch.cs | Subject validation rejects malformed subjects | | `ErrSubscribePermissionViolation` | golang/nats-server/server/errors.go:205 | PORTED | src/NATS.Server/NatsClient.cs | Subscribe permission check | | `ErrNoTransforms` | golang/nats-server/server/errors.go:208 | PORTED | src/NATS.Server/Server/ServerErrorConstants.cs:26 | Added parity error literal constant | | `ErrCertNotPinned` | golang/nats-server/server/errors.go:211 | PORTED | src/NATS.Server/Tls/TlsHelper.cs | Pinned cert validation | | `ErrDuplicateServerName` | golang/nats-server/server/errors.go:215 | PORTED | src/NATS.Server/Routes/ | Duplicate server name on cluster connect | | `ErrMinimumVersionRequired` | golang/nats-server/server/errors.go:218 | PORTED | src/NATS.Server/Routes/ | Minimum version enforcement on cluster | | `ErrInvalidMappingDestination` | golang/nats-server/server/errors.go:221 | PORTED | src/NATS.Server/Subscriptions/SubjectTransform.cs | Transform destination validation | | `ErrInvalidMappingDestinationSubject` | golang/nats-server/server/errors.go:223 | PORTED | src/NATS.Server/Subscriptions/SubjectTransform.cs | Invalid destination subject | | `ErrMappingDestinationNotUsingAllWildcards` | golang/nats-server/server/errors.go:226 | PORTED | src/NATS.Server/Subscriptions/SubjectTransform.cs | Wildcard coverage check | | `ErrUnknownMappingDestinationFunction` | golang/nats-server/server/errors.go:229 | PORTED | src/NATS.Server/Subscriptions/SubjectTransform.cs | Unknown function error | | `ErrMappingDestinationIndexOutOfRange` | golang/nats-server/server/errors.go:232 | PORTED | src/NATS.Server/Subscriptions/SubjectTransform.cs | Index out of range | | `ErrMappingDestinationNotEnoughArgs` | golang/nats-server/server/errors.go:235 | PORTED | src/NATS.Server/Subscriptions/SubjectTransform.cs | Not enough args error | | `ErrMappingDestinationInvalidArg` | golang/nats-server/server/errors.go:238 | PORTED | src/NATS.Server/Subscriptions/SubjectTransform.cs | Invalid arg error | | `ErrMappingDestinationTooManyArgs` | golang/nats-server/server/errors.go:241 | PORTED | src/NATS.Server/Subscriptions/SubjectTransform.cs | Too many args error | | `ErrMappingDestinationNotSupportedForImport` | golang/nats-server/server/errors.go:244 | PORTED | src/NATS.Server/Subscriptions/SubjectTransform.cs | Import-only wildcard restriction | | `mappingDestinationErr` (type) | golang/nats-server/server/errors.go:248 | PORTED | src/NATS.Server/Subscriptions/SubjectTransform.cs | Equivalent validation exceptions in transform code | | `mappingDestinationErr.Error` | golang/nats-server/server/errors.go:253 | PORTED | src/NATS.Server/Subscriptions/SubjectTransform.cs | Exception message formatting | | `mappingDestinationErr.Is` | golang/nats-server/server/errors.go:257 | NOT_APPLICABLE | — | Go `errors.Is` interface; .NET uses `is` and `catch (SpecificException)` instead | | `configErr` (type) | golang/nats-server/server/errors.go:261 | PORTED | src/NATS.Server/Configuration/ConfigProcessor.cs:1434 | `ConfigProcessorException` with error list | | `configErr.Source` | golang/nats-server/server/errors.go:267 | PARTIAL | src/NATS.Server/Configuration/ConfigProcessor.cs | Source file/line tracking in errors is partial; exception message includes context but not file:line:col | | `configErr.Error` | golang/nats-server/server/errors.go:272 | PORTED | src/NATS.Server/Configuration/ConfigProcessor.cs | Exception `Message` property | | `unknownConfigFieldErr` (type) | golang/nats-server/server/errors.go:280 | PORTED | src/NATS.Server/Configuration/ConfigProcessor.cs:1597 | Added `UnknownConfigFieldWarning` type with field/source metadata and Go-style warning message (`unknown field `). | | `configWarningErr` (type) | golang/nats-server/server/errors.go:292 | PORTED | src/NATS.Server/Configuration/ConfigProcessor.cs:1588 | Added `ConfigWarningException` base warning type to distinguish warning payloads from hard errors. | | `processConfigErr` (type) | golang/nats-server/server/errors.go:303 | PORTED | src/NATS.Server/Configuration/ConfigProcessor.cs:1434 | `ConfigProcessorException` accumulates all errors | | `processConfigErr.Error` | golang/nats-server/server/errors.go:310 | PORTED | src/NATS.Server/Configuration/ConfigProcessor.cs | `Message` + `Errors` list | | `processConfigErr.Warnings` | golang/nats-server/server/errors.go:322 | PORTED | src/NATS.Server/Configuration/ConfigProcessor.cs:1581 | Added `ConfigProcessorException.Warnings` list and wired unknown top-level field warnings into thrown config errors when validation errors are present. | | `processConfigErr.Errors` | golang/nats-server/server/errors.go:327 | PORTED | src/NATS.Server/Configuration/ConfigProcessor.cs:1437 | `ConfigProcessorException.Errors` property | | `errCtx` (type) | golang/nats-server/server/errors.go:332 | PORTED | tests/NATS.Server.Tests/InfrastructureGoParityTests.cs:1069 | `WrappedNatsException` (test-file-scoped) mirrors the error context wrapping; production code uses standard .NET exception chaining | | `NewErrorCtx` | golang/nats-server/server/errors.go:338 | PORTED | tests/NATS.Server.Tests/InfrastructureGoParityTests.cs:1069 | Equivalent via `new WrappedNatsException(inner, ctx)` in tests; production uses `new Exception(msg, inner)` | | `errCtx.Unwrap` | golang/nats-server/server/errors.go:343 | NOT_APPLICABLE | — | Go `errors.Unwrap` interface; .NET uses `Exception.InnerException` | | `errCtx.Context` | golang/nats-server/server/errors.go:350 | PORTED | tests/NATS.Server.Tests/InfrastructureGoParityTests.cs:1069 | `WrappedNatsException.FullTrace()` extracts and returns context | | `UnpackIfErrorCtx` | golang/nats-server/server/errors.go:358 | PORTED | tests/NATS.Server.Tests/InfrastructureGoParityTests.cs:1075 | `WrappedNatsException.FullTrace()` — recursive trace assembly matches Go's `UnpackIfErrorCtx` logic | | `errorsUnwrap` (unexported) | golang/nats-server/server/errors.go:371 | NOT_APPLICABLE | — | Go 1.13 compatibility shim; .NET uses `Exception.InnerException` directly | | `ErrorIs` | golang/nats-server/server/errors.go:382 | NOT_APPLICABLE | — | Go 1.13 compatibility shim for `errors.Is`; .NET uses `is`, `catch`, or `Exception.GetType()` | ### `golang/nats-server/server/errors_gen.go` | Go Symbol | Go File:Line | Status | .NET Equivalent | Notes | |-----------|:-------------|--------|:----------------|-------| | (entire file — code generator) | golang/nats-server/server/errors_gen.go:1 | NOT_APPLICABLE | — | This is a `//go:build ignore` code generator that produces `jetstream_errors_generated.go`. The generated JetStream API error codes are ported directly as `JetStreamApiError` and integer error code constants in `src/NATS.Server/JetStream/Api/`. No need to port the generator itself. | ### `golang/nats-server/server/sdm.go` | Go Symbol | Go File:Line | Status | .NET Equivalent | Notes | |-----------|:-------------|--------|:----------------|-------| | `SDMMeta` (type) | golang/nats-server/server/sdm.go:22 | MISSING | — | Subject Delete Marker metadata tracker; used inside `stream.go` for SDM/KV purge tracking. MsgScheduling not yet ported so SDMMeta is also absent. | | `SDMBySeq` (type) | golang/nats-server/server/sdm.go:27 | MISSING | — | Per-sequence SDM state (last flag + timestamp); needed by `SDMMeta` | | `newSDMMeta` | golang/nats-server/server/sdm.go:33 | MISSING | — | Constructor for `SDMMeta` | | `isSubjectDeleteMarker` (unexported) | golang/nats-server/server/sdm.go:42 | MISSING | — | Header inspection to detect SDM or KV purge markers; needed for FileStore tombstone handling | | `SDMMeta.empty` | golang/nats-server/server/sdm.go:47 | MISSING | — | Clear all tracking state | | `SDMMeta.trackPending` | golang/nats-server/server/sdm.go:56 | MISSING | — | Cache a pending SDM sequence | | `SDMMeta.removeSeqAndSubject` | golang/nats-server/server/sdm.go:66 | MISSING | — | Remove a confirmed SDM from tracking | ### `golang/nats-server/server/scheduler.go` | Go Symbol | Go File:Line | Status | .NET Equivalent | Notes | |-----------|:-------------|--------|:----------------|-------| | `ErrMsgScheduleInvalidVersion` | golang/nats-server/server/scheduler.go:29 | MISSING | — | Error for unknown schedule snapshot version; needed when decoding binary schedule state | | `MsgScheduling` (type) | golang/nats-server/server/scheduler.go:35 | MISSING | — | Core message scheduler type — manages per-subject schedules, timer, THW integration; tests in FileStoreTombstoneTests.cs note this is not yet ported | | `MsgSchedule` (type) | golang/nats-server/server/scheduler.go:46 | MISSING | — | Per-subject schedule entry (seq + timestamp) | | `newMsgScheduling` | golang/nats-server/server/scheduler.go:51 | MISSING | — | Constructor with run callback | | `MsgScheduling.add` | golang/nats-server/server/scheduler.go:61 | MISSING | — | Add/replace a schedule entry | | `MsgScheduling.init` (unexported) | golang/nats-server/server/scheduler.go:66 | MISSING | — | Internal init with THW integration | | `MsgScheduling.update` | golang/nats-server/server/scheduler.go:81 | MISSING | — | Update timestamp of existing schedule | | `MsgScheduling.markInflight` | golang/nats-server/server/scheduler.go:93 | MISSING | — | Mark subject as currently being delivered | | `MsgScheduling.isInflight` | golang/nats-server/server/scheduler.go:99 | MISSING | — | Check if subject is in-flight | | `MsgScheduling.remove` | golang/nats-server/server/scheduler.go:104 | MISSING | — | Remove by sequence number | | `MsgScheduling.removeSubject` | golang/nats-server/server/scheduler.go:111 | MISSING | — | Remove by subject | | `MsgScheduling.clearInflight` | golang/nats-server/server/scheduler.go:119 | MISSING | — | Reset all in-flight tracking | | `MsgScheduling.resetTimer` (unexported) | golang/nats-server/server/scheduler.go:123 | MISSING | — | Recalculate next fire time from THW | | `MsgScheduling.getScheduledMessages` (unexported) | golang/nats-server/server/scheduler.go:158 | MISSING | — | Evaluate expired schedules; complex — includes pattern parsing, header manipulation | | `MsgScheduling.encode` | golang/nats-server/server/scheduler.go:249 | MISSING | — | Binary snapshot serialization | | `MsgScheduling.decode` | golang/nats-server/server/scheduler.go:267 | MISSING | — | Binary snapshot deserialization | | `parseMsgSchedule` (unexported) | golang/nats-server/server/scheduler.go:302 | MISSING | — | Parse `@at ...` / `@every ...` schedule patterns | ### `golang/nats-server/server/ats/ats.go` | Go Symbol | Go File:Line | Status | .NET Equivalent | Notes | |-----------|:-------------|--------|:----------------|-------| | `TickInterval` (const) | golang/nats-server/server/ats/ats.go:25 | MISSING | — | 100ms tick interval constant for access-time service | | `Register` | golang/nats-server/server/ats/ats.go:42 | MISSING | — | Start the access-time goroutine (ref-counted). Used by FileStore on creation to get efficient nanosecond timestamps without calling `time.Now()` on every access. | | `Unregister` | golang/nats-server/server/ats/ats.go:64 | MISSING | — | Stop the access-time goroutine when last user unregisters | | `AccessTime` | golang/nats-server/server/ats/ats.go:76 | MISSING | — | Return cached Unix nanosecond timestamp (atomic load). .NET equivalent could use `Interlocked`-cached `DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()` but no such service exists yet | ### `golang/nats-server/server/elastic/elastic.go` | Go Symbol | Go File:Line | Status | .NET Equivalent | Notes | |-----------|:-------------|--------|:----------------|-------| | `Pointer[T]` (generic type) | golang/nats-server/server/elastic/elastic.go:26 | MISSING | — | Elastic (weak/strong) reference wrapper using Go 1.24 `weak.Pointer`. Used for FileStore block caching to allow GC to reclaim blocks while keeping a strong ref when needed. No .NET equivalent ported. | | `Make[T]` | golang/nats-server/server/elastic/elastic.go:20 | MISSING | — | Factory for `Pointer[T]` from a strong pointer | | `Pointer[T].Set` | golang/nats-server/server/elastic/elastic.go:31 | MISSING | — | Update the weak/strong pointer | | `Pointer[T].Strengthen` | golang/nats-server/server/elastic/elastic.go:38 | MISSING | — | Promote weak ref to strong | | `Pointer[T].Weaken` | golang/nats-server/server/elastic/elastic.go:45 | MISSING | — | Demote strong ref to weak (allow GC) | | `Pointer[T].Value` | golang/nats-server/server/elastic/elastic.go:52 | MISSING | — | Get current value (strong if available, else weak) | ### `golang/nats-server/server/tpm/js_ek_tpm_windows.go` and `js_ek_tpm_other.go` | Go Symbol | Go File:Line | Status | .NET Equivalent | Notes | |-----------|:-------------|--------|:----------------|-------| | `JsKeyTPMVersion` | golang/nats-server/server/tpm/js_ek_tpm_windows.go:34 | DEFERRED | — | TPM version constant; entire TPM subsystem deferred | | `regenerateSRK` (unexported) | golang/nats-server/server/tpm/js_ek_tpm_windows.go:51 | DEFERRED | — | Windows-only TPM2 SRK creation | | `natsTPMPersistedKeys` (type) | golang/nats-server/server/tpm/js_ek_tpm_windows.go:77 | DEFERRED | — | JSON-serializable key blob struct | | `writeTPMKeysToFile` (unexported) | golang/nats-server/server/tpm/js_ek_tpm_windows.go:85 | DEFERRED | — | Persist TPM key blobs to disk | | `readTPMKeysFromFile` (unexported) | golang/nats-server/server/tpm/js_ek_tpm_windows.go:115 | DEFERRED | — | Read TPM key blobs from disk | | `createAndSealJsEncryptionKey` (unexported) | golang/nats-server/server/tpm/js_ek_tpm_windows.go:146 | DEFERRED | — | Create NKey-based JetStream encryption key and seal to TPM | | `unsealJsEncrpytionKey` (unexported) | golang/nats-server/server/tpm/js_ek_tpm_windows.go:178 | DEFERRED | — | Unseal JetStream key from TPM | | `policyPCRPasswordSession` (unexported) | golang/nats-server/server/tpm/js_ek_tpm_windows.go:203 | DEFERRED | — | TPM2 policy session with PCR + password | | `LoadJetStreamEncryptionKeyFromTPM` | golang/nats-server/server/tpm/js_ek_tpm_windows.go:245 | DEFERRED | — | Main entry point; Windows only. Non-Windows stub returns error. Deferred: requires `Microsoft.TPM` or `Tss.Net` NuGet and Windows-only API surface. | | `LoadJetStreamEncryptionKeyFromTPM` (stub) | golang/nats-server/server/tpm/js_ek_tpm_other.go:21 | NOT_APPLICABLE | — | Non-Windows stub; .NET would use `PlatformNotSupportedException` equivalently | ### `golang/nats-server/internal/fastrand/fastrand.go` | Go Symbol | Go File:Line | Status | .NET Equivalent | Notes | |-----------|:-------------|--------|:----------------|-------| | `Uint32` | golang/nats-server/internal/fastrand/fastrand.go:12 | NOT_APPLICABLE | — | Links to `runtime.fastrand` via `go:linkname` — a Go runtime internal. .NET uses `Random.Shared.Next()` or `RandomNumberGenerator` equivalently. No need to port this internal. | | `Uint32n` | golang/nats-server/internal/fastrand/fastrand.go:17 | NOT_APPLICABLE | — | Same as above; maps to `Random.Shared.Next(0, n)` | | `Uint64` | golang/nats-server/internal/fastrand/fastrand.go:20 | NOT_APPLICABLE | — | Same as above; maps to `Random.Shared.NextInt64()` | ### `golang/nats-server/internal/ldap/dn.go` | Go Symbol | Go File:Line | Status | .NET Equivalent | Notes | |-----------|:-------------|--------|:----------------|-------| | `AttributeTypeAndValue` (type) | golang/nats-server/internal/ldap/dn.go:30 | PARTIAL | src/NATS.Server/Auth/TlsMapAuthenticator.cs | .NET `X500DistinguishedName` used directly; no standalone `AttributeTypeAndValue` type | | `RelativeDN` (type) | golang/nats-server/internal/ldap/dn.go:37 | PARTIAL | src/NATS.Server/Auth/TlsMapAuthenticator.cs | `X500DistinguishedName.EnumerateRelativeDistinguishedNames()` provides equivalent; no custom `RelativeDN` type | | `DN` (type) | golang/nats-server/internal/ldap/dn.go:43 | PARTIAL | src/NATS.Server/Auth/TlsMapAuthenticator.cs | `X500DistinguishedName` (.NET BCL) used instead; no custom `DN` type | | `FromCertSubject` | golang/nats-server/internal/ldap/dn.go:48 | PARTIAL | src/NATS.Server/Auth/TlsMapAuthenticator.cs:31 | Certificate subject extracted via `X509Certificate2.SubjectName`; does not support multi-value RDNs or full RFC 4514 ordering | | `FromRawCertSubject` | golang/nats-server/internal/ldap/dn.go:80 | MISSING | — | Raw ASN.1 subject parsing preserving original order; not implemented | | `ParseDN` | golang/nats-server/internal/ldap/dn.go:126 | MISSING | — | RFC 4514 DN string parser; not implemented. .NET uses `X500DistinguishedName` which parses RFC 2253 format but lacks the Go implementation's special-case handling | | `DN.Equal` | golang/nats-server/internal/ldap/dn.go:220 | MISSING | — | RFC 4517 distinguishedNameMatch comparison | | `DN.RDNsMatch` | golang/nats-server/internal/ldap/dn.go:234 | MISSING | — | Order-independent RDN matching | | `DN.AncestorOf` | golang/nats-server/internal/ldap/dn.go:258 | MISSING | — | DN ancestry check | | `RelativeDN.Equal` | golang/nats-server/internal/ldap/dn.go:278 | MISSING | — | RFC 4517 RDN equivalence | | `RelativeDN.hasAllAttributes` (unexported) | golang/nats-server/internal/ldap/dn.go:285 | MISSING | — | Attribute superset check | | `AttributeTypeAndValue.Equal` | golang/nats-server/internal/ldap/dn.go:302 | MISSING | — | Case-insensitive type + value comparison | ### `golang/nats-server/internal/antithesis/` | Go Symbol | Go File:Line | Status | .NET Equivalent | Notes | |-----------|:-------------|--------|:----------------|-------| | `AssertUnreachable` (noop build) | golang/nats-server/internal/antithesis/noop.go:24 | NOT_APPLICABLE | — | Chaos testing assertion (noop when Antithesis SDK not active); .NET has no Antithesis SDK. xUnit's `Assert.Fail()` covers the reachability assertion pattern in tests. | | `Assert` (noop build) | golang/nats-server/internal/antithesis/noop.go:27 | NOT_APPLICABLE | — | Same as above; .NET uses Shouldly `condition.ShouldBeTrue()` in tests | | `AssertUnreachable` (SDK build) | golang/nats-server/internal/antithesis/test_assert.go:49 | NOT_APPLICABLE | — | Antithesis SDK wrapper; no .NET Antithesis SDK exists | | `Assert` (SDK build) | golang/nats-server/internal/antithesis/test_assert.go:83 | NOT_APPLICABLE | — | Same as above | ### `golang/nats-server/internal/testhelper/` (ocsp.go / logging.go) | Go Symbol | Go File:Line | Status | .NET Equivalent | Notes | |-----------|:-------------|--------|:----------------|-------| | `NewOCSPResponder` | golang/nats-server/internal/testhelper/ocsp.go (ocsp.go):45 | PORTED | tests/NATS.Server.Tests/OcspStaplingTests.cs | .NET OCSP test helper implemented inline in test files using ASP.NET Core minimal APIs | | `NewOCSPResponderCustomAddress` | golang/nats-server/internal/testhelper/ocsp.go:40 | PORTED | tests/NATS.Server.Tests/OcspStaplingTests.cs | Equivalent test helper | | `NewOCSPResponderDesignatedCustomAddress` | golang/nats-server/internal/testhelper/ocsp.go:50 | PORTED | tests/NATS.Server.Tests/OcspStaplingTests.cs | Designated responder variant | | `NewOCSPResponderPreferringHTTPMethod` | golang/nats-server/internal/testhelper/ocsp.go:55 | PORTED | tests/NATS.Server.Tests/OcspStaplingTests.cs | HTTP method preference variant | | `NewOCSPResponderCustomTimeout` | golang/nats-server/internal/testhelper/ocsp.go:60 | PORTED | tests/NATS.Server.Tests/OcspStaplingTests.cs | Custom TTL variant | | `NewOCSPResponderBase` | golang/nats-server/internal/testhelper/ocsp.go:65 | PORTED | tests/NATS.Server.Tests/OcspStaplingTests.cs | Base factory; all OCSP responder variants collapse to this | | `GetOCSPStatus` | golang/nats-server/internal/testhelper/ocsp.go:230 | PORTED | tests/NATS.Server.Tests/OcspStaplingTests.cs | OCSP status extraction from TLS connection state | | `SetOCSPStatus` | golang/nats-server/internal/testhelper/ocsp.go:251 | PORTED | tests/NATS.Server.Tests/OcspStaplingTests.cs | HTTP POST to set cert status on mock OCSP responder | --- ## .NET-Only Implementations (No Direct Go Equivalent) The following .NET types were added to support the porting but have no exact Go counterpart: | .NET Type | File | Notes | |-----------|------|-------| | `OutboundBufferPool` | `src/NATS.Server/IO/OutboundBufferPool.cs` | Tiered byte-array pool (512/4096/65536) replacing Go's `sync.Pool` + `[]byte` dynamic sizing | | `AdaptiveReadBuffer` | `src/NATS.Server/IO/AdaptiveReadBuffer.cs` | Buffer sizing state machine; mirrors `client.go` readLoop buffer growth/shrink logic | | `AcceptLoopErrorHandler` | `src/NATS.Server/Server/AcceptLoopErrorHandler.cs` | Callback-based accept error delegation (no Go equivalent; Go logs inline) | | `TlsRateLimiter` | `src/NATS.Server/Tls/TlsRateLimiter.cs` | Async token-bucket rate limiter for TLS handshakes | --- ## Keeping This File Updated After porting work is completed: 1. **Update status**: Change `MISSING → PORTED` or `PARTIAL → PORTED` for each item completed 2. **Add .NET path**: Fill in the ".NET Equivalent" column with the actual file:line 3. **Re-count LOC**: Update the LOC numbers in `stillmissing.md`: ```bash # Re-count .NET source LOC for this module find src/NATS.Server/IO/ src/NATS.Server/Server/ -name '*.cs' -type f -exec cat {} + | wc -l # Re-count .NET test LOC for this module find tests/NATS.Server.Tests/IO/ -name '*.cs' -type f -exec cat {} + | wc -l ``` 4. **Add a changelog entry** below with date and summary of what was ported 5. **Update the parity DB** if new test mappings were created: ```bash sqlite3 docs/test_parity.db "INSERT INTO test_mappings (go_test_id, dotnet_test_id, confidence, notes) VALUES (?, ?, 'manual', 'ported in YYYY-MM-DD session')" ``` ## Change Log | Date | Change | By | |------|--------|----| | 2026-02-26 | Ported config warning parity slice: added `ConfigWarningException`, `UnknownConfigFieldWarning`, and `ConfigProcessorException.Warnings`; wired unknown top-level fields as warning entries and added focused configuration parity tests. | codex | | 2026-02-25 | File created with LLM analysis instructions | auto | | 2026-02-25 | Full gap inventory populated — all Go source files analyzed, 131 symbols classified | auto | | 2026-02-25 | Ported missing `errors.go` parity literals into `ServerErrorConstants` and added targeted parity tests for the newly added constants | codex |