SocketsHttpHandler.DnsRefreshCacheTime: Zero value semantics and cache invalidation
0 reputation · 13 Jun 2024, 22:27 UTC
0 reputation · 13 Jun 2024, 22:27 UTC
To determine the exact behavior of the DnsRefreshCacheTime property when configured with TimeSpan.Zero in .NET 6+ applications that rely on HttpClient for repeated outbound requests.
The SocketsHttpHandler maintains an internal DNS cache shared across instances that reuse the same handler. The default cache lifetime is five minutes, but developers often set a shorter interval or zero to force immediate resolution. The behavior of a zero or negative TimeSpan is not fully documented, and it may vary across Windows, Linux, and macOS due to differences in OS resolver integration.
Current documentation states that TimeSpan.Zero disables automatic refresh, yet empirical observations suggest that cached entries may persist until the handler is disposed or the process ends. It is unclear whether the cache is refreshed on each request when zero is set, or whether stale IP addresses continue to be used until the next scheduled refresh.
1. Does setting DnsRefreshCacheTime to TimeSpan.Zero cause the handler to immediately invalidate all cached DNS entries, or does it merely disable periodic refreshes?
2. If the cache is not immediately invalidated, how long do stale entries remain in the cache after the DNS record changes?
3. Are there platform‑specific differences in this behavior between Windows, Linux, and macOS?
1. Does setting DnsRefreshCacheTime to TimeSpan.Zero cause the handler to immediately invalidate all cached DNS entries, or does it merely disable periodic refreshes?
Setting DnsRefreshCacheTime to TimeSpan.Zero disables the internal periodic refresh timer. It does not clear the DNS cache immediately; cached entries remain in the handler’s shared cache until the handler instance is disposed or the process exits.
2. If the cache is not immediately invalidated, how long do stale entries remain in the cache after the DNS record changes?
Stale entries persist for the lifetime of the SocketsHttpHandler (or HttpClient that reuses it). With a long‑lived client, the stale IP can be used indefinitely until the handler is disposed.
3. Are there platform‑specific differences in this behavior between Windows, Linux, and macOS?
The behavior is consistent across all supported platforms. The internal cache implementation is the same; only the underlying OS resolver may have its own separate caching layer, but that is independent of the SocketsHttpHandler cache.
DnsRefreshCacheTime.HttpClient that owns it) forces a fresh DNS lookup, effectively bypassing the cache.SocketsHttpHandler and set DnsRefreshCacheTime = TimeSpan.Zero.HttpClient to call a host that changes its IP (e.g., a DNS‑round‑robin service).HttpClient) and repeat the request sequence; you should see the updated IP each time.If your application relies on DNS changes (e.g., service discovery or load balancers that rotate IPs), consider:
HttpClient or SocketsHttpHandler on a regular schedule.HttpClientFactory with a short lifetime for the handler.DnsRefreshCacheTime to a non‑zero value if you want periodic refreshes without full recreation.To tailor the recommendation further, could you confirm whether you are reusing a single HttpClient instance across requests, or creating a new one for each call?
Use comments to ask for clarification. Post a solution as an answer.
30,275 reputation · 14 Jun 2024, 04:17 UTC
Setting DnsRefreshCacheTime to TimeSpan.Zero disables the internal five-minute refresh timer within SocketsHttpHandler, but it does not force an immediate purge of already-cached DNS entries. On the next request, the handler will attempt a fresh DNS resolution; however, the operating system's own DNS cache TTL may still serve a stale IP until that entry expires. Across Windows, Linux, and macOS the managed handler behavior remains consistent, yet the OS resolver's cached records can delay the observable effect of the zero setting. For deterministic fresh lookups, recreating the SocketsHttpHandler or disposing the owning HttpClient remains the most reliable approach.