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
- Check the actual resource names/types present via Kernel32Util.getResourceNames(path) before calling getResource
- Use MAKEINTRESOURCE-style integer IDs (new Pointer(id)) when the resource is stored by integer ID instead of a name string
- Verify the module path points to the right binary that actually contains the resource
- 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
- Call getResourceNames(path) first and check the type/name exists
- Match integer-ID vs string-name encoding to how the resource was compiled
- Verify the target binary actually contains the needed resource with a resource viewer
- Log the Win32Exception errorCode to distinguish 1813 vs 1814
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
- Win32Exception from native GetLastError after LoadResource f
- Win32Exception from native GetLastError when SizeofResource
- LockResource returned null.
- Win32Exception from native GetLastError after EnumResourceTy
- Win32Exception from native GetLastError after EnumResourceNa
AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12).
Data as JSON: /api/errors/bb1904094cea79e9.
Report an issue: GitHub.