java-native-access/jna · warning · IllegalArgumentException
Bad volume GUID path format:
Error message
Bad volume GUID path format:
What it means
extractVolumeGUID extracts the bare GUID from a volume path like \\?\Volume{GUID}\ by stripping the known prefix and suffix. It throws IllegalArgumentException when the input is null, too short, or does not start with \\?\Volume{ and end with }\. This is a pure client-side format validation — no native call is involved, so GetLastError is irrelevant here.
Source
Thrown at contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java:906
/**
* Parses and returns the pure GUID value of a volume name obtained
* from {@link Kernel32#FindFirstVolume(char[], int)} or
* {@link Kernel32#FindNextVolume} calls
*
* @param volumeGUIDPath
* The volume GUID path as returned by one of the above mentioned calls
* @return The pure GUID value after stripping the "\\?\" prefix and
* removing the trailing backslash.
* @throws IllegalArgumentException if bad format encountered
* @see <A HREF="https://msdn.microsoft.com/en-us/library/windows/desktop/aa365248(v=vs.85).aspx">Naming a Volume</A>
*/
public static final String extractVolumeGUID(String volumeGUIDPath) {
if ((volumeGUIDPath == null)
|| (volumeGUIDPath.length() <= (VOLUME_GUID_PATH_PREFIX.length() + VOLUME_GUID_PATH_SUFFIX.length()))
|| (!volumeGUIDPath.startsWith(VOLUME_GUID_PATH_PREFIX))
|| (!volumeGUIDPath.endsWith(VOLUME_GUID_PATH_SUFFIX))) {
throw new IllegalArgumentException("Bad volume GUID path format: " + volumeGUIDPath);
}
return volumeGUIDPath.substring(VOLUME_GUID_PATH_PREFIX.length(), volumeGUIDPath.length() - VOLUME_GUID_PATH_SUFFIX.length());
}
/**
* This function retrieves the full path of the executable file of a given process identifier.
*
* @param pid
* Identifier for the running process
* @param dwFlags
* 0 - The name should use the Win32 path format.
* 1(WinNT.PROCESS_NAME_NATIVE) - The name should use the native system path format.
*
* @return the full path of the process's executable file of null if failed. To get extended error information,
* call GetLastError.
*/
public static final String QueryFullProcessImageName(int pid, int dwFlags) {View on GitHub (pinned to d036ad9781)
Solutions
- Pass the full volume path exactly as returned by FindFirstVolume/GetVolumeNameForVolumeMountPoint, including trailing backslash.
- Validate the format with a regex ^\\\\\?\\Volume\{[0-9a-fA-F-]+\}\\$ before calling.
- If you only have a bare GUID, rebuild the path: "\\\\?\\Volume{" + guid + "}\\".
- Catch IllegalArgumentException at call boundaries accepting user/registry-supplied strings.
Example fix
// before
String guid = Kernel32Util.extractVolumeGUID("{abcd1234}"); // throws
// after
String path = "{abcd1234}".matches("^\\\\\\?\\\\Volume\\{.+\\}\\\\$")
? "{abcd1234}"
: "\\\\?\\Volume{" + "{abcd1234}" + "}\\";
String guid = Kernel32Util.extractVolumeGUID(path); Defensive patterns
Strategy: validation
Validate before calling
static final Pattern VOLUME_GUID = Pattern.compile("^\\\\\\?\\\\Volume\\{([0-9a-fA-F\\-]+)\\}\\\\$");
Matcher m = VOLUME_GUID.matcher(volumeGUIDPath);
if (!m.matches()) throw new IllegalArgumentException(volumeGUIDPath);
String guid = m.group(1); // same result as extractVolumeGUID, validated first Type guard
static boolean isWellFormedVolumeGuidPath(String s) {
return s != null && s.matches("^\\\\\\?\\\\Volume\\{[0-9a-fA-F\\-]+\\}\\\\$");
} Try / catch
try {
guid = Kernel32Util.extractVolumeGUID(path);
} catch (IllegalArgumentException e) {
LOG.warn("Malformed volume path: " + path);
guid = null;
} Prevention
- Keep the trailing backslash — it is part of the required format.
- Only feed paths straight from FindFirstVolume/GetVolumeNameForVolumeMountPoint into the extractor.
- Do not pass an already-extracted GUID back into the extractor.
- Use a regex pre-check when input comes from users or the registry.
When it happens
Trigger: Calling Kernel32Util.extractVolumeGUID with null, an empty string, a bare GUID without the \\?\Volume{...}\ wrapper, a path missing the trailing backslash, or a drive letter like "C:\".
Common situations: Passing the output of GetVolumeNameForVolumeMountPoint that was concatenated or trimmed incorrectly; stripping the backslash with a manual substring; passing the extracted GUID back in instead of the full path; hardcoding a GUID string and mistyping braces.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- Win32Exception from GetLastError after GetVolumePathNamesFor
- Win32Exception from native GetLastError on retry of GetVolum
- LookupAccountNameW was expected to fail with ERROR_INSUFFICI
- Expected GetTokenInformation to fail with ERROR_INSUFFICIENT
- Failed to find privilege "{privilege}" - {GetLastError}
AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12).
Data as JSON: /api/errors/67e2fcf3a673b396.
Report an issue: GitHub.