.NET 11 NO_PROXY CIDR support lets HttpClient bypass an environment-configured proxy when a request URI contains an IPv4 or IPv6 address inside an approved subnet. That closes a practical gap for .NET services that call private IP endpoints but still send public traffic through a corporate egress proxy.

The change is deliberately narrow. CIDR matching applies to literal IP hosts; it does not resolve a DNS name and compare the resulting address with the subnet. A production configuration therefore needs separate CIDR entries for private IP calls and hostname or domain-suffix entries for named internal services.

Configure .NET 11 NO_PROXY CIDR for private IPs

Assume an Azure-hosted worker reaches a private API at 10.42.8.25, while normal internet requests must use an egress proxy. Configure the proxy variables before the .NET process starts:

HTTPS_PROXY=http://proxy.internal.contoso:8080
HTTP_PROXY=http://proxy.internal.contoso:8080
NO_PROXY=127.0.0.0/8,10.42.0.0/16,fd12:3456::/48,.internal.contoso.net

The two CIDR entries cover literal private IPv4 and IPv6 hosts. The domain-suffix entry handles names such as orders.internal.contoso.net. Keep both forms when the application legitimately calls services by IP and by name; one is not a substitute for the other.

The application can continue using the normal HttpClient pipeline. Do not add a custom proxy selector merely to duplicate the environment configuration:

using System.Net.Http;

var handler = new SocketsHttpHandler
{
    UseProxy = true,
    ConnectTimeout = TimeSpan.FromSeconds(5)
};

using var client = new HttpClient(handler)
{
    Timeout = TimeSpan.FromSeconds(15)
};

using HttpResponseMessage response =
    await client.GetAsync("https://10.42.8.25/healthz");

response.EnsureSuccessStatusCode();

When SocketsHttpHandler.Proxy remains null and proxy use is enabled, the runtime can use the environment proxy. On .NET 11, the request above matches 10.42.0.0/16 and bypasses that proxy. Explicitly assigning a different IWebProxy changes the ownership of this decision, so verify that application code or a library has not replaced the default behavior.

Understand exactly what the bypass list matches

The .NET 11 implementation parses comma-separated bypass entries when it builds the environment proxy. Entries accepted as IP networks are stored separately from host and domain entries. For each request, CIDR matching runs only when the URI host can be parsed as an IP address.

  • https://10.42.8.25/healthz matches 10.42.0.0/16.
  • https://10.43.8.25/healthz does not match that subnet.
  • https://[fd12:3456::25]/healthz matches fd12:3456::/48.
  • https://orders.internal.contoso.net/ is evaluated as a hostname, even if DNS later returns 10.42.8.25.

The hostname case is the easiest production mistake. Proxy selection does not perform DNS resolution just to test a CIDR range. If internal callers use private DNS, include the exact host or an appropriately scoped domain suffix in NO_PROXY. Avoid broad suffixes that bypass inspection for unrelated services.

Before .NET 11, a value such as 10.42.0.0/16 was not interpreted as a network range by this environment-proxy implementation. Upgrading the runtime is therefore part of the change; adding the CIDR entry alone does not provide the same behavior to older deployments.

Apply the configuration to an Azure-hosted .NET service

Store the proxy and bypass values in the hosting environment rather than branching application code by Azure resource name. For an App Service staging slot, Container Apps revision, or another managed host, apply the variables to the candidate deployment and restart it so new handlers are constructed from the intended settings.

Treat the bypass list as a routing policy:

  • List only subnets the application is authorized and able to reach directly.
  • Use the narrowest practical prefix instead of bypassing an entire private-address family.
  • Keep named private endpoints in explicit hostname or suffix entries.
  • Manage proxy credentials through the platform’s secret mechanism; do not commit credentials inside an environment file.
  • Review outbound firewall, NSG, route-table, and private-DNS behavior separately. NO_PROXY chooses a client route; it does not create network reachability.

A direct request may still fail because the host has no route, DNS is wrong, TLS does not trust the private endpoint certificate, or an outbound rule blocks the connection. Keep those failures distinct from proxy-selection failures so operators do not widen the bypass list to hide a network or certificate problem.

Verify direct and proxied routes

Do not accept a successful HTTP status as complete proof. The proxy may have forwarded the private request successfully, which is precisely the routing mistake this change is meant to prevent. Verify both sides of the path in a non-production slot or revision.

static async Task ProbeAsync(HttpClient client, string name, Uri target)
{
    try
    {
        using HttpResponseMessage response = await client.GetAsync(target);
        Console.WriteLine(
            $"{name}: {(int)response.StatusCode} {response.StatusCode}");
    }
    catch (Exception ex)
    {
        Console.WriteLine($"{name}: {ex.GetType().Name}: {ex.Message}");
    }
}

using var handler = new SocketsHttpHandler
{
    UseProxy = true,
    ConnectTimeout = TimeSpan.FromSeconds(5)
};

using var client = new HttpClient(handler)
{
    Timeout = TimeSpan.FromSeconds(15)
};

await ProbeAsync(client, "inside-v4",
    new Uri("https://10.42.8.25/healthz"));
await ProbeAsync(client, "outside-v4",
    new Uri("https://10.43.8.25/healthz"));
await ProbeAsync(client, "inside-v6",
    new Uri("https://[fd12:3456::25]/healthz"));
await ProbeAsync(client, "named-internal",
    new Uri("https://orders.internal.contoso.net/healthz"));
await ProbeAsync(client, "public",
    new Uri("https://example.com/"));

The probe deliberately includes addresses just inside and outside the configured prefix. Run it with approved test endpoints, then correlate its timestamps with the internal service access log and the proxy access log.

ProbeExpected routeEvidence
10.42.8.25DirectPrivate service records the request; proxy records no matching target.
10.43.8.25ProxyProxy records the target or applies its expected deny policy.
fd12:3456::25DirectIPv6 service records the request; proxy does not.
orders.internal.contoso.netDirect by suffixThe hostname entry, not the CIDR entry, supplies the bypass.
example.comProxyProxy records the public request.

If the test environment cannot expose proxy logs, use a dedicated test proxy that rejects or marks requests to the private canary. Do not infer route selection from latency alone; caching, TLS setup, DNS, and connection reuse make that evidence unreliable.

Handle lifecycle, security, and failure boundaries

The runtime parses the bypass list when the environment proxy is constructed. Treat a proxy-policy change as deployment configuration: update the slot or revision, restart the process, and verify new requests. Do not assume an already-created handler or pooled client will observe an in-process environment-variable mutation.

CIDR support removes a routing workaround; it is not an authorization control. A bypassed request no longer passes through the configured proxy, so the destination must still enforce TLS, identity, authorization, and request validation. Security teams should review whether the proxy previously supplied required inspection, audit, or egress policy before a subnet is added.

Also protect against configuration drift. Emit the runtime version and a redacted policy fingerprint at startup, but never log proxy credentials or the full proxy URL. Track direct-connect failures, proxy failures, TLS errors, and destination status codes separately. A sudden rise in direct-connect failures after rollout usually points to an incorrect prefix or missing route, not a reason to disable certificate validation.

Roll out with compatibility and rollback controls

Compile and run the application on the intended .NET 11 build before depending on CIDR behavior. Pin the SDK and make its selection visible in CI; the .NET 11 SDK health CI guide provides a useful prerequisite for keeping preview and servicing builds auditable.

Roll out to one staging slot or low-traffic revision first. Confirm the five-route matrix, compare proxy traffic by destination, and watch direct connection, TLS, and timeout metrics. Then increase traffic gradually while keeping the previous runtime and bypass configuration available as one rollback unit.

For a mixed-runtime deployment, do not assume every instance interprets CIDR entries identically. Either keep the old exact-host entries until all instances run .NET 11, or split the rollout so requests that require CIDR bypass reach only upgraded instances. Roll back by restoring the earlier environment configuration and runtime together; changing only one side can leave different instances making different routing decisions.

Adoption checklist

  • Confirm the service actually uses the environment proxy rather than an explicitly assigned IWebProxy.
  • Run on .NET 11 before relying on CIDR parsing.
  • Add narrow IPv4 and IPv6 prefixes only for approved direct destinations.
  • Keep explicit hostname or domain-suffix entries for private DNS names.
  • Restart the process after changing proxy policy.
  • Verify inside, outside, IPv6, named-internal, and public targets.
  • Correlate application, destination, and proxy logs instead of trusting status or latency alone.
  • Review TLS, authorization, inspection, and audit requirements for bypassed traffic.
  • Roll out gradually and keep runtime plus environment configuration together in the rollback plan.

References

Found this useful? Support more practical developer content.

Author

Practical .NET, Angular, Azure, Blazor, and AI engineering for real-world development.

Write A Comment

Ads Blocker Image Powered by Code Help Pro

Ads Blocker Detected!!!

We have detected that you are using extensions to block ads. Please support us by disabling these ads blocker.

Powered By
100% Free SEO Tools - Tool Kits PRO