{"record":{"id":"23c31cdb0e32da5a","repo":"dotnet/wpf","slug":"win32exception-uses-last-error-code","errorCode":null,"errorMessage":"Win32Exception (uses last error code)","messagePattern":"Win32Exception \\(uses last error code\\)","errorType":"exception","errorClass":"Win32Exception","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/AppModel/CookieHandler.cs","lineNumber":120,"sourceCode":"    internal static string GetCookie(Uri uri, bool throwIfNoCookie)\n    {\n        UInt32 size = 0;\n        string uriString = BindUriHelper.UriToString(uri);\n        if (UnsafeNativeMethods.InternetGetCookieEx(uriString, null, null, ref size, 0, IntPtr.Zero))\n        {\n            Debug.Assert(size > 0);\n            size++;\n            System.Text.StringBuilder sb = new System.Text.StringBuilder((int)size);\n            // PresentationHost intercepts InternetGetCookieEx(). It will set the INTERNET_COOKIE_THIRD_PARTY\n            // flag if necessary.\n            if (UnsafeNativeMethods.InternetGetCookieEx(uriString, null, sb, ref size, 0, IntPtr.Zero))\n            {\n                return sb.ToString();\n            }\n        }\n        if (!throwIfNoCookie && Marshal.GetLastWin32Error() == NativeMethods.ERROR_NO_MORE_ITEMS)\n            return null;\n        throw new Win32Exception(/*uses last error code*/);\n    }\n\n    internal static bool SetCookie(Uri uri, string cookieData)\n    {\n        return SetCookieUnsafe(uri, cookieData, null);\n    }\n\n    private static bool SetCookieUnsafe(Uri uri, string cookieData, string p3pHeader)\n    {\n        string uriString = BindUriHelper.UriToString(uri);\n        // PresentationHost intercepts InternetSetCookieEx(). It will set the INTERNET_COOKIE_THIRD_PARTY\n        // flag if necessary. (This doesn't look very elegant but is much simpler than having to make the \n        // 3rd party decision here as well or calling into the native code (from PresentationCore).)\n        uint res = UnsafeNativeMethods.InternetSetCookieEx(\n            uriString, null, cookieData, UnsafeNativeMethods.INTERNET_COOKIE_EVALUATE_P3P, p3pHeader);\n        if(res == 0)\n            throw new Win32Exception(/*uses last error code*/);\n        return res != UnsafeNativeMethods.COOKIE_STATE_REJECT;","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/AppModel/CookieHandler.cs#L102-L138","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","solutions":["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).","Verify the Uri is absolute, http/https, and matches the domain the cookie was set with (cookies are per-domain/path).","If you only want 'cookie present or not', call with throwIfNoCookie=false so ERROR_NO_MORE_ITEMS returns null instead of throwing.","Run in the same interactive user context that owns the cookie store; wininet cookie APIs fail from services/session-0 contexts."],"exampleFix":"// before (throws for any native failure)\nstring cookie = CookieHandler.GetCookie(uri, \"session\", true);\n\n// after\nstring cookie = CookieHandler.GetCookie(uri, \"session\", false); // null when no cookie\nif (cookie == null)\n{\n    // handle absence explicitly instead of an exception\n}","handlingStrategy":"try-catch","validationCode":"// pre-validate the uri and call with throwIfNoCookie=false when absence is acceptable\nif (uri == null || !uri.IsAbsoluteUri ||\n    (uri.Scheme != Uri.UriSchemeHttp && uri.Scheme != Uri.UriSchemeHttps))\n{\n    throw new ArgumentException(\"Cookie lookup requires an absolute http/https Uri.\", nameof(uri));\n}","typeGuard":null,"tryCatchPattern":"try\n{\n    cookie = CookieHandler.GetCookie(uri, name, throwIfNoCookie: false);\n}\ncatch (Win32Exception ex)\n{\n    Log.Warn($\"Native cookie lookup failed (Win32 {ex.NativeErrorCode}) for {uri}.\");\n    cookie = null;\n}","preventionTips":["Call GetCookie with throwIfNoCookie=false when a missing cookie is an expected outcome.","Use absolute http/https Uris matching the domain the cookie was set on.","Run in the interactive user session that owns the wininet cookie store - not from services.","Inspect Win32Exception.NativeErrorCode (e.g. 87 = bad parameter, 5 = access denied) to diagnose the native cause."],"tags":["win32","cookies","interop","wpf"],"backgroundTag":"http-error-response","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-22T01:17:13.364Z"}