java-native-access/jna · error · RuntimeException
Unsupported empty type:
Error message
Unsupported empty type:
What it means
When enumerating all values of a key (registryGetValues), the library handles the case where lpcbData is 0 (an empty value). For an empty value whose type is one of the known string/number kinds it returns a default empty object, and WinNT.REG_NONE maps to null; any other type with zero-length data reaches the default branch and throws this RuntimeException. It signals the value is empty AND of a type the library does not know how to represent emptily.
Source
Thrown at contrib/platform/src/com/sun/jna/platform/win32/Advapi32Util.java:2173
case WinNT.REG_BINARY: {
keyValues.put(nameString, new byte[0]);
break;
}
case WinNT.REG_SZ:
case WinNT.REG_EXPAND_SZ: {
keyValues.put(nameString, new char[0]);
break;
}
case WinNT.REG_MULTI_SZ: {
keyValues.put(nameString, new String[0]);
break;
}
case WinNT.REG_NONE: {
keyValues.put(nameString, null);
break;
}
default:
throw new RuntimeException("Unsupported empty type: "
+ lpType.getValue());
}
continue;
}
switch (lpType.getValue()) {
case WinNT.REG_QWORD: {
keyValues.put(nameString, byteData.getLong(0));
break;
}
case WinNT.REG_DWORD: {
keyValues.put(nameString, byteData.getInt(0));
break;
}
case WinNT.REG_SZ:
case WinNT.REG_EXPAND_SZ: {
if (W32APITypeMapper.DEFAULT == W32APITypeMapper.UNICODE) {
keyValues.put(nameString, byteData.getWideString(0));View on GitHub (pinned to d036ad9781)
Solutions
- Catch RuntimeException per key when enumerating, log the offending value name/type, and continue with the remaining values.
- Read only the specific values you need with typed getters instead of enumerating the whole key.
- If you control the writer, use standard types (REG_SZ, REG_DWORD, REG_BINARY) and avoid exotic types like REG_LINK.
- Update JNA - support for additional registry types in enumeration has improved in later releases.
Example fix
// before
TreeMap<String, Object> all = Advapi32Util.registryGetValues(root, key); // throws on exotic empty type
// after
try {
TreeMap<String, Object> all = Advapi32Util.registryGetValues(root, key);
} catch (RuntimeException e) {
LOG.warn("Skipping key with unsupported empty value type: {}", key, e);
} Defensive patterns
Strategy: try-catch
Validate before calling
// inspect value types before bulk enumeration Advapi32Util.InfoKey info = Advapi32Util.registryQueryInfoKey(key, 0); // max value len/type info // per-value type check: // IntByReference lpType from Advapi32.INSTANCE.RegQueryValueEx(...) then compare against known types
Try / catch
try { return Advapi32Util.registryGetValues(key); }
catch (RuntimeException e) { log.warn("Unsupported empty value type in {}: {}", key, e.getMessage()); return Collections.emptyMap(); } Prevention
- Avoid hardware/Enum keys with resource-descriptor values when enumerating
- Enumerate value names via registryGetKeys/RegEnumValue and decode selectively
- Whitelist the value names you consume instead of trusting the whole key
- Keep JNA updated for wider type coverage
When it happens
Trigger: Calling Advapi32Util.registryGetValues(key) or registryGetValues(root, key, samDesiredExtra) on a key containing a zero-byte value whose type is not one of REG_SZ/REG_EXPAND_SZ/REG_BINARY(most types accepted)/REG_DWORD/REG_QWORD/REG_MULTI_SZ/REG_NONE - e.g. an exotic or corrupted type like REG_LINK or REG_RESOURCE_LIST with zero data.
Common situations: Enumerating driver/hardware keys (HKLM\SYSTEM\CurrentControlSet\Enum) that contain REG_RESOURCE_LIST / REG_FULL_RESOURCE_DESCRIPTOR values; keys created by third-party tools writing unusual types; corrupted registry entries.
Related errors
- Unsupported type:
- Unexpected registry type + lpType.getValue() + , expected RE
- Unexpected registry type {}, expected REG_SZ
- Unexpected registry type {}, expected REG_BINARY
- Unexpected registry type {}, expected REG_DWORD
AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12).
Data as JSON: /api/errors/f79de720ab8f445e.
Report an issue: GitHub.