Skip to content

Docs: iOS/MAUI cookie handling workaround #2387

@alexeyzimarev

Description

@alexeyzimarev

Context

Set-Cookie headers are silently stripped from responses on iOS / Mac Catalyst when HttpClient is backed by NSUrlSessionHandler (the MAUI default). NSURLSession consumes the cookie into NSHTTPCookieStorage.SharedStorage before the header is surfaced to .NET, so RestSharp's ParseResponseCookies finds nothing to parse and RestResponse.Cookies is empty.

RestSharp can't fix this in the core library without either pulling iOS workload dependencies into a netstandard2.0 package (unacceptable) or adopting a cookie-pooling strategy that re-introduces cross-tenant cookie leaks (the very reason UseCookies = false is the default).

The fix is to suppress NSURLSession's native cookie handling so the header reaches .NET intact. This belongs in the docs.

See #2168 (root-cause discussion) and #2385 (duplicate with the cleanest reproducer).

What to add

A page under "Advanced topics" (or near "Cookies") titled something like iOS / MAUI cookie handling with:

  1. Symptom description: Set-Cookie missing on iOS, works on Android/Windows/Linux.

  2. Root cause one-liner: NSURLSession intercepts the header before .NET sees it.

  3. The recipe:

    #if IOS || MACCATALYST
    using Foundation;
    
    var options = new RestClientOptions(baseUrl) {
        ConfigureMessageHandler = _ => {
            var config = NSUrlSessionConfiguration.DefaultSessionConfiguration;
            config.HttpCookieStorage      = null;
            config.HttpCookieAcceptPolicy = NSHttpCookieAcceptPolicy.Never;
            return new NSUrlSessionHandler(config);
        }
    };
    #endif
  4. Why this preserves multi-tenant safety: no cookie storage anywhere except RestSharp's per-request CookieContainer, so cookies cannot leak between calls or between tenants sharing a RestClient.

  5. What not to do: set HttpClientHandler.UseCookies = true with a shared CookieContainer. It "works" but pools cookies across every call made on that client — broken for multi-tenant use.

Acceptance criteria

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions