java-native-access/jna · error · Win32Exception

Win32Exception (error code from Native.getLastError after Fi

Error message

Win32Exception (error code from Native.getLastError after FindFirstUrlCacheEntry)

What it means

WininetUtil.getCache() throws a Win32Exception carrying the Win32 error code returned by Native.getLastError() when the first call to FindFirstUrlCacheEntry fails with an error other than ERROR_NO_MORE_ITEMS, ERROR_SUCCESS, or ERROR_INSUFFICIENT_BUFFER. The exception's error code maps to a human-readable Win32 message, telling you why cache enumeration could not start (e.g. access denied or the URL cache service is unavailable).

Source

Thrown at contrib/platform/src/com/sun/jna/platform/win32/WininetUtil.java:72

        int lastError = 0;

        // return
        Map<String, String> cacheItems = new LinkedHashMap<>();

        try {
            IntByReference size = new IntByReference();

            // for every entry, we call the API twice:
            // once to get the size into the IntByReference
            // then again to get the actual item
            cacheHandle = Wininet.INSTANCE.FindFirstUrlCacheEntry(null, null, size);
            lastError = Native.getLastError();

            // if there's nothing in the cache, we're done.
            if (lastError == WinError.ERROR_NO_MORE_ITEMS) {
                return cacheItems;
            } else if (lastError != WinError.ERROR_SUCCESS && lastError != WinError.ERROR_INSUFFICIENT_BUFFER) {
                throw new Win32Exception(lastError);
            }

            INTERNET_CACHE_ENTRY_INFO entry = new INTERNET_CACHE_ENTRY_INFO(size.getValue());
            cacheHandle = Wininet.INSTANCE.FindFirstUrlCacheEntry(null, entry, size);

            if (cacheHandle == null) {
                throw new Win32Exception(Native.getLastError());
            }

            items.add(entry);

            while (true) {
                size = new IntByReference();

                // for every entry, we call the API twice:
                // once to get the size into the IntByReference
                // then again to get the actual item
                boolean result = Wininet.INSTANCE.FindNextUrlCacheEntry(cacheHandle, null, size);

View on GitHub (pinned to d036ad9781)

Solutions

  1. Check the exception's Win32 error code (we.getHR().intValue() / HRESULT from code) to identify the precise cause, then address that condition (e.g. run as an interactive user with a cache)
  2. Handle ERROR_NO_MORE_ITEMS and ERROR_INSUFFICIENT_BUFFER as non-fatal — the library already does; ensure you are not confusing a first-call buffer retry with a hard failure
  3. Verify the process runs in a user session with a WinINet profile loaded (not a session-0 service without user profile)
  4. Wrap getCache() in try/catch (Win32Exception) and fall back to an empty list or alternate enumeration mechanism

Example fix

// before
List<INTERNET_CACHE_ENTRY_INFO> items = WininetUtil.getCache();
// after
List<INTERNET_CACHE_ENTRY_INFO> items;
try {
    items = WininetUtil.getCache();
} catch (Win32Exception e) {
    log.warn("IE cache enumeration failed: " + e.getMessage());
    items = Collections.emptyList();
}
Defensive patterns

Strategy: try-catch

Try / catch

try {
    items = WininetUtil.getCache();
} catch (Win32Exception e) {
    switch (e.getErrorCode()) { /* inspect HRESULT */ }
    items = Collections.emptyList();
}

Prevention

When it happens

Trigger: Wininet.INSTANCE.FindFirstUrlCacheEntry(null, null, size) fails and GetLastError is not one of the three tolerated codes — e.g. ERROR_FILE_NOT_FOUND / ERROR_INTERNET_* conditions, or the WinINet cache is inaccessible for the current user/session.

Common situations: Running under a service account or session with no WinINet cache (cache APIs are per-user and require an interactive user profile); calling from an elevated process into a different user's cache; restricted environments where URLMON/WinINet caching is disabled by policy.

Related errors


AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12). Data as JSON: /api/errors/848567aa6f09af27. Report an issue: GitHub.