java-native-access/jna · error · Win32Exception

Win32Exception from native GetLastError after FindResource f

Error message

Win32Exception from native GetLastError after FindResource failed

What it means

Kernel32Util throws this Win32Exception when Kernel32.INSTANCE.FindResource returns null while looking up a resource in a loaded module. GetLastError is read immediately after the native call and its code is wrapped into a Win32Exception, so the exception's error code is the native Win32 error (e.g. ERROR_RESOURCE_TYPE_NOT_FOUND 1813 / ERROR_RESOURCE_NAME_NOT_FOUND 1814). It means the requested resource type/name could not be located in the target module.

Source

Thrown at contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java:1011

            Pointer t = null;
            try {
                t = new Pointer(Long.parseLong(type));
            } catch (NumberFormatException e) {
                t = new Memory(Native.WCHAR_SIZE * (type.length() + 1));
                t.setWideString(0, type);
            }

            Pointer n = null;
            try {
                n = new Pointer(Long.parseLong(name));
            } catch (NumberFormatException e) {
                n = new Memory(Native.WCHAR_SIZE * (name.length() + 1));
                n.setWideString(0, name);
            }

            HRSRC hrsrc = Kernel32.INSTANCE.FindResource(target, n, t);
            if (hrsrc == null) {
                throw new Win32Exception(Kernel32.INSTANCE.GetLastError());
            }

            // according to MSDN, on 32 bit Windows or newer, calling FreeResource() is not necessary - and in fact does nothing but return false.
            HANDLE loaded = Kernel32.INSTANCE.LoadResource(target, hrsrc);
            if (loaded == null) {
                throw new Win32Exception(Kernel32.INSTANCE.GetLastError());
            }

            length = Kernel32.INSTANCE.SizeofResource(target, hrsrc);
            if (length == 0) {
                throw new Win32Exception(Kernel32.INSTANCE.GetLastError());
            }

            // MSDN: It is not necessary to unlock resources because the system automatically deletes them when the process that created them terminates.
            // MSDN does not say that LockResource sets GetLastError
            start = Kernel32.INSTANCE.LockResource(loaded);
            if (start == null) {
                throw new IllegalStateException("LockResource returned null.");

View on GitHub (pinned to d036ad9781)

Solutions

  1. Check the actual resource names/types present via Kernel32Util.getResourceNames(path) before calling getResource
  2. Use MAKEINTRESOURCE-style integer IDs (new Pointer(id)) when the resource is stored by integer ID instead of a name string
  3. Verify the module path points to the right binary that actually contains the resource
  4. Inspect the Win32Exception's errorCode for ERROR_RESOURCE_TYPE_NOT_FOUND (1813) or ERROR_RESOURCE_NAME_NOT_FOUND (1814) and adjust the query accordingly

Example fix

// before
byte[] data = Kernel32Util.getResource(path, "VERSIONINFO", "#1");
// after
Map<String, List<String>> names = Kernel32Util.getResourceNames(path);
if (names.containsKey("VERSIONINFO")) {
    byte[] data = Kernel32Util.getResource(path, "VERSIONINFO", "#1");
} else {
    throw new IllegalStateException("No VERSIONINFO resource in " + path);
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Java: verify resource exists before extraction
Map<String, List<String>> names = Kernel32Util.getResourceNames(path);
if (!names.containsKeyOrDefault) { } // check names.get("VERSIONINFO") contains "#1" before getResource

Type guard

boolean hasResource(String path, String type, String name) {
    List<String> n = Kernel32Util.getResourceNames(path).get(type);
    return n != null && n.contains(name);
}

Try / catch

try {
    byte[] data = Kernel32Util.getResource(target, type, name);
} catch (Win32Exception e) {
    if (e.getErrorCode().intValue() == 1813 || e.getErrorCode().intValue() == 1814) {
        // resource type/name not found — handle absence
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Calling Kernel32Util.getResource(target, resType, resName, langId) (or overload) where the module contains no resource matching the given type and name, e.g. requesting a VERSIONINFO ('#1') from a DLL that has no version resource, or passing a string name when the resource is stored under an integer ID.

Common situations: Passing a plain executable path whose resources use integer IDs while the caller passes names (or vice versa), querying a resource in a library that was stripped of resources, typos in resource type/name constants, wrong language ID variant.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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