java-native-access/jna · error · RuntimeException
Unexpected registry type {}, expected REG_SZ
Error message
Unexpected registry type {}, expected REG_SZ What it means
registryGetMultiStringValue sizes the value with RegQueryValueEx and then asserts that the reported type is WinNT.REG_MULTI_SZ; if not, it throws this RuntimeException. The message text says 'expected REG_SZ', but the actual check is against REG_MULTI_SZ - the thrown message is misleading about the expected type. The guard prevents interpreting non multi-string data as a String[].
Source
Thrown at contrib/platform/src/com/sun/jna/platform/win32/Advapi32Util.java:952
* Get a registry REG_MULTI_SZ value.
*
* @param hKey
* Parent Key.
* @param value
* Name of the value to retrieve.
* @return String value.
*/
public static String[] registryGetStringArray(HKEY hKey, String value) {
IntByReference lpcbData = new IntByReference();
IntByReference lpType = new IntByReference();
int rc = Advapi32.INSTANCE.RegQueryValueEx(hKey, value, 0,
lpType, (char[]) null, lpcbData);
if (rc != W32Errors.ERROR_SUCCESS
&& rc != W32Errors.ERROR_INSUFFICIENT_BUFFER) {
throw new Win32Exception(rc);
}
if (lpType.getValue() != WinNT.REG_MULTI_SZ) {
throw new RuntimeException("Unexpected registry type "
+ lpType.getValue() + ", expected REG_SZ");
}
// Allocate enougth memroy to hold value and ensure terminating
// double NULL chars are present
Memory data = new Memory(lpcbData.getValue() + 2 * Native.WCHAR_SIZE);
data.clear();
rc = Advapi32.INSTANCE.RegQueryValueEx(hKey, value, 0,
lpType, data, lpcbData);
if (rc != W32Errors.ERROR_SUCCESS
&& rc != W32Errors.ERROR_INSUFFICIENT_BUFFER) {
throw new Win32Exception(rc);
}
return regMultiSzBufferToStringArray(data);
}
/**
* Convert the null-delimited buffer of strings returned from registry values of
* type {@link WinNT#REG_MULTI_SZ} to an array of strings.View on GitHub (pinned to d036ad9781)
Solutions
- Check the value's type with registryQueryInfoKey or registryGetValue and use the matching typed getter.
- If the value is a single REG_SZ, use registryGetStringValue and wrap it in a one-element array.
- Recreate the registry value with type REG_MULTI_SZ (e.g. via PowerShell New-ItemProperty -PropertyType MultiString).
- Catch RuntimeException and fall back to a single-string read joined into an array.
Example fix
// before
String[] list = Advapi32Util.registryGetMultiStringValue(root, key, "Servers");
// after
Object v = Advapi32Util.registryGetValue(root, key, "Servers");
String[] list = (v instanceof String[])
? (String[]) v
: new String[]{ String.valueOf(v) }; Defensive patterns
Strategy: validation
Validate before calling
Object v = Advapi32Util.registryGetValue(root, keyPath, valueName);
if (!(v instanceof String[])) throw new IllegalStateException("Expected REG_MULTI_SZ for " + valueName); Type guard
boolean isMultiString(Object v) { return v instanceof String[]; } Try / catch
try { return Advapi32Util.registryGetMultiStringValue(root, key, value); }
catch (RuntimeException e) { log.warn("Value {} is not REG_MULTI_SZ", value); return Collections.emptyList(); } Prevention
- Write REG_MULTI_SZ values with matching MultiString property type
- Verify type after external tools modify the key
- Use generic registryGetValue plus instanceof when the type may vary
- Note the exception message may say REG_SZ even when REG_MULTI_SZ is expected
When it happens
Trigger: Calling Advapi32Util.registryGetMultiStringValue(key, valueName) (or the root/key/value overload) on a registry value whose actual type is anything other than REG_MULTI_SZ, e.g. REG_SZ, REG_EXPAND_SZ or REG_DWORD.
Common situations: A value that once held a multi-string list was replaced by a plain string; documentation assumes REG_MULTI_SZ but the installer writes REG_SZ; copying values between keys via reg export/import changed the type.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Unexpected registry type + lpType.getValue() + , expected RE
- Unexpected registry type {}, expected REG_BINARY
- Unexpected registry type {}, expected REG_DWORD
- Unexpected registry type {}, expected REG_QWORD
- Unexpected registry type + lpType.getValue() + , expected RE
AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12).
Data as JSON: /api/errors/3fb50bfe97d5db69.
Report an issue: GitHub.