{"record":{"id":"3fb50bfe97d5db69","repo":"java-native-access/jna","slug":"unexpected-registry-type-expected-reg-sz","errorCode":null,"errorMessage":"Unexpected registry type {}, expected REG_SZ","messagePattern":"Unexpected registry type (.+?), expected REG_SZ","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"contrib/platform/src/com/sun/jna/platform/win32/Advapi32Util.java","lineNumber":952,"sourceCode":"     * Get a registry REG_MULTI_SZ value.\n     *\n     * @param hKey\n     *            Parent Key.\n     * @param value\n     *            Name of the value to retrieve.\n     * @return String value.\n     */\n    public static String[] registryGetStringArray(HKEY hKey, String value) {\n        IntByReference lpcbData = new IntByReference();\n        IntByReference lpType = new IntByReference();\n        int rc = Advapi32.INSTANCE.RegQueryValueEx(hKey, value, 0,\n                lpType, (char[]) null, lpcbData);\n        if (rc != W32Errors.ERROR_SUCCESS\n                && rc != W32Errors.ERROR_INSUFFICIENT_BUFFER) {\n            throw new Win32Exception(rc);\n        }\n        if (lpType.getValue() != WinNT.REG_MULTI_SZ) {\n            throw new RuntimeException(\"Unexpected registry type \"\n                    + lpType.getValue() + \", expected REG_SZ\");\n        }\n                // Allocate enougth memroy to hold value and ensure terminating\n                // double NULL chars are present\n        Memory data = new Memory(lpcbData.getValue() + 2 * Native.WCHAR_SIZE);\n        data.clear();\n        rc = Advapi32.INSTANCE.RegQueryValueEx(hKey, value, 0,\n                lpType, data, lpcbData);\n        if (rc != W32Errors.ERROR_SUCCESS\n                && rc != W32Errors.ERROR_INSUFFICIENT_BUFFER) {\n            throw new Win32Exception(rc);\n        }\n        return regMultiSzBufferToStringArray(data);\n    }\n\n    /**\n     * Convert the null-delimited buffer of strings returned from registry values of\n     * type {@link WinNT#REG_MULTI_SZ} to an array of strings.","sourceCodeStart":934,"sourceCodeEnd":970,"githubUrl":"https://github.com/java-native-access/jna/blob/d036ad9781adad4b66693e8fa7098e4ac665e0a3/contrib/platform/src/com/sun/jna/platform/win32/Advapi32Util.java#L934-L970","documentation":"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[].","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nString[] list = Advapi32Util.registryGetMultiStringValue(root, key, \"Servers\");\n\n// after\nObject v = Advapi32Util.registryGetValue(root, key, \"Servers\");\nString[] list = (v instanceof String[])\n    ? (String[]) v\n    : new String[]{ String.valueOf(v) };","handlingStrategy":"validation","validationCode":"Object v = Advapi32Util.registryGetValue(root, keyPath, valueName);\nif (!(v instanceof String[])) throw new IllegalStateException(\"Expected REG_MULTI_SZ for \" + valueName);","typeGuard":"boolean isMultiString(Object v) { return v instanceof String[]; }","tryCatchPattern":"try { return Advapi32Util.registryGetMultiStringValue(root, key, value); }\ncatch (RuntimeException e) { log.warn(\"Value {} is not REG_MULTI_SZ\", value); return Collections.emptyList(); }","preventionTips":["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"],"tags":["windows-registry","type-mismatch","reg-multi-sz","jna"],"backgroundTag":"type-mismatch","analyzedSha":"d036ad9781adad4b66693e8fa7098e4ac665e0a3","analyzedAt":"2026-09-12T06:50:59.239Z","contentChangedAt":"2026-09-12T06:50:59.239Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}