dotnet/wpf · error · Win32Exception

Win32Exception (uses last error code)

Error message

Win32Exception (uses last error code)

What it means

CookieHandler.GetCookie throws a Win32Exception constructed with the last Win32 error when the native InternetGetCookie call fails and the failure is not the benign ERROR_NO_MORE_ITEMS case (and throwIfNoCookie is set). The exception's message and ErrorCode come from the Win32 error code, so the underlying reason is whatever the native cookie API reported (e.g. access denied, invalid parameter, buffer failure).

Solutions

  1. Check the Win32Exception.NativeErrorCode to identify the actual Win32 failure and address that specific cause (e.g. 87 invalid parameter for a malformed Uri, 5 access denied).
  2. Verify the Uri is absolute, http/https, and matches the domain the cookie was set with (cookies are per-domain/path).
  3. If you only want 'cookie present or not', call with throwIfNoCookie=false so ERROR_NO_MORE_ITEMS returns null instead of throwing.
  4. Run in the same interactive user context that owns the cookie store; wininet cookie APIs fail from services/session-0 contexts.

Example fix

// before (throws for any native failure)
string cookie = CookieHandler.GetCookie(uri, "session", true);

// after
string cookie = CookieHandler.GetCookie(uri, "session", false); // null when no cookie
if (cookie == null)
{
    // handle absence explicitly instead of an exception
}
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-validate the uri and call with throwIfNoCookie=false when absence is acceptable
if (uri == null || !uri.IsAbsoluteUri ||
    (uri.Scheme != Uri.UriSchemeHttp && uri.Scheme != Uri.UriSchemeHttps))
{
    throw new ArgumentException("Cookie lookup requires an absolute http/https Uri.", nameof(uri));
}

Try / catch

try
{
    cookie = CookieHandler.GetCookie(uri, name, throwIfNoCookie: false);
}
catch (Win32Exception ex)
{
    Log.Warn($"Native cookie lookup failed (Win32 {ex.NativeErrorCode}) for {uri}.");
    cookie = null;
}

Prevention

When it happens

Trigger: Calling CookieHandler.GetCookie (or the 'cookies' wrapper) with throwIfNoCookie true for a URI where the native Internet cookie API (InternetGetCookie/InternetGetCookieEx) fails with a Win32 error other than ERROR_NO_MORE_ITEMS - e.g. wininet not initialized for this session, an invalid/malformed Uri, or a permission/security-zone failure.

Common situations: Reading cookies set by a hosted WebBrowser/WebView in the same wininet session when the session state is broken; passing a URI whose scheme/host the native cookie store rejects; running in an environment where wininet per-user cookie storage is inaccessible (service accounts, session-0); version differences where the returned code no longer matches ERROR_NO_MORE_ITEMS.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/23c31cdb0e32da5a. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/AppModel/CookieHandler.cs:120

    internal static string GetCookie(Uri uri, bool throwIfNoCookie)
    {
        UInt32 size = 0;
        string uriString = BindUriHelper.UriToString(uri);
        if (UnsafeNativeMethods.InternetGetCookieEx(uriString, null, null, ref size, 0, IntPtr.Zero))
        {
            Debug.Assert(size > 0);
            size++;
            System.Text.StringBuilder sb = new System.Text.StringBuilder((int)size);
            // PresentationHost intercepts InternetGetCookieEx(). It will set the INTERNET_COOKIE_THIRD_PARTY
            // flag if necessary.
            if (UnsafeNativeMethods.InternetGetCookieEx(uriString, null, sb, ref size, 0, IntPtr.Zero))
            {
                return sb.ToString();
            }
        }
        if (!throwIfNoCookie && Marshal.GetLastWin32Error() == NativeMethods.ERROR_NO_MORE_ITEMS)
            return null;
        throw new Win32Exception(/*uses last error code*/);
    }

    internal static bool SetCookie(Uri uri, string cookieData)
    {
        return SetCookieUnsafe(uri, cookieData, null);
    }

    private static bool SetCookieUnsafe(Uri uri, string cookieData, string p3pHeader)
    {
        string uriString = BindUriHelper.UriToString(uri);
        // PresentationHost intercepts InternetSetCookieEx(). It will set the INTERNET_COOKIE_THIRD_PARTY
        // flag if necessary. (This doesn't look very elegant but is much simpler than having to make the 
        // 3rd party decision here as well or calling into the native code (from PresentationCore).)
        uint res = UnsafeNativeMethods.InternetSetCookieEx(
            uriString, null, cookieData, UnsafeNativeMethods.INTERNET_COOKIE_EVALUATE_P3P, p3pHeader);
        if(res == 0)
            throw new Win32Exception(/*uses last error code*/);
        return res != UnsafeNativeMethods.COOKIE_STATE_REJECT;

View on GitHub (pinned to 81131a70a4)