{"record":{"id":"7e92a70011a445b0","repo":"java-native-access/jna","slug":"win32exception-error-code-from-native-getlasterror-after-7e92a7","errorCode":null,"errorMessage":"Win32Exception (error code from Native.getLastError after FindFirstUrlCacheEntry with buffer)","messagePattern":"Win32Exception \\(error code from Native\\.getLastError after FindFirstUrlCacheEntry with buffer\\)","errorType":"error_code","errorClass":"Win32Exception","httpStatus":null,"severity":"error","filePath":"contrib/platform/src/com/sun/jna/platform/win32/WininetUtil.java","lineNumber":79,"sourceCode":"\n            // for every entry, we call the API twice:\n            // once to get the size into the IntByReference\n            // then again to get the actual item\n            cacheHandle = Wininet.INSTANCE.FindFirstUrlCacheEntry(null, null, size);\n            lastError = Native.getLastError();\n\n            // if there's nothing in the cache, we're done.\n            if (lastError == WinError.ERROR_NO_MORE_ITEMS) {\n                return cacheItems;\n            } else if (lastError != WinError.ERROR_SUCCESS && lastError != WinError.ERROR_INSUFFICIENT_BUFFER) {\n                throw new Win32Exception(lastError);\n            }\n\n            INTERNET_CACHE_ENTRY_INFO entry = new INTERNET_CACHE_ENTRY_INFO(size.getValue());\n            cacheHandle = Wininet.INSTANCE.FindFirstUrlCacheEntry(null, entry, size);\n\n            if (cacheHandle == null) {\n                throw new Win32Exception(Native.getLastError());\n            }\n\n            items.add(entry);\n\n            while (true) {\n                size = new IntByReference();\n\n                // for every entry, we call the API twice:\n                // once to get the size into the IntByReference\n                // then again to get the actual item\n                boolean result = Wininet.INSTANCE.FindNextUrlCacheEntry(cacheHandle, null, size);\n\n                if (!result) {\n                    lastError = Native.getLastError();\n                    if (lastError == WinError.ERROR_NO_MORE_ITEMS) {\n                        break;\n                    } else if (lastError != WinError.ERROR_SUCCESS && lastError != WinError.ERROR_INSUFFICIENT_BUFFER) {\n                        throw new Win32Exception(lastError);","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/java-native-access/jna/blob/d036ad9781adad4b66693e8fa7098e4ac665e0a3/contrib/platform/src/com/sun/jna/platform/win32/WininetUtil.java#L61-L97","documentation":"WininetUtil.getCache() throws this Win32Exception when FindFirstUrlCacheEntry is called WITH an allocated INTERNET_CACHE_ENTRY_INFO buffer (after the sizing call) and returns a null handle, meaning the second invocation itself failed. The exception carries Native.getLastError(), distinguishing it from the pre-buffer sizing failure. Typically this means the entry disappeared between calls or the previously reported buffer size was no longer valid.","triggerScenarios":"Calling WininetUtil.getCache() when, after allocating the buffer of the size reported by the first FindFirstUrlCacheEntry call, the buffered FindFirstUrlCacheEntry(null, entry, size) still returns null — cache was flushed concurrently, or the size call raced with cache changes.","commonSituations":"Concurrent modification of the browser cache while enumerating (another process deleting entries); very large cache entries exceeding the allocated size; transient WinINet errors under heavy load.","solutions":["Retry getCache() — transient races between the sizing call and the buffered call are the usual cause","Catch Win32Exception and treat as an empty/failed enumeration rather than a fatal error if cache data is optional","Ensure enumeration runs in the same user session that owns the cache and that no concurrent cache purge is in progress","If it persists, upgrade JNA / verify the INTERNET_CACHE_ENTRY_INFO structure size matches the WinINet version"],"exampleFix":"// before\nList<INTERNET_CACHE_ENTRY_INFO> items = WininetUtil.getCache();\n// after\nList<INTERNET_CACHE_ENTRY_INFO> items;\ntry {\n    items = WininetUtil.getCache();\n} catch (Win32Exception e) {\n    items = Collections.emptyList();\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    items = WininetUtil.getCache();\n} catch (Win32Exception e) {\n    items = retryOrEmpty(); // retry once, then empty list\n}","preventionTips":["Expect races: the cache can change between sizing and buffered calls","Retry the full enumeration once on failure","Avoid enumerating while other processes purge the cache"],"tags":["wininet","windows","url-cache","race-condition"],"backgroundTag":"api-error-response","analyzedSha":"d036ad9781adad4b66693e8fa7098e4ac665e0a3","analyzedAt":"2026-09-12T06:50:59.239Z","contentChangedAt":"2026-09-12T06:50:59.239Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}