apache/hadoop · error · IOException
unexpected URISyntaxException
Error message
unexpected URISyntaxException
What it means
getLocalDestination() (used by -get/-copyToLocal, and other commands whose destination is local) wraps the last argument in java.net.URI. If the string violates RFC 2396 syntax, URISyntaxException is caught; on Windows the code falls back to PathData parsing to support drive-letter paths, but on Linux/MacOS it is rethrown as IOException('unexpected URISyntaxException'). So the local destination contains characters java.net.URI cannot parse: a Windows drive-letter path on a non-Windows host, spaces, or other URI-illegal characters.
Source
Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/shell/CommandWithDestination.java:192
}
/**
* The last arg is expected to be a local path, if only one argument is
* given then the destination will be the current directory
* @param args is the list of arguments
* @throws IOException raised on errors performing I/O.
*/
protected void getLocalDestination(LinkedList<String> args)
throws IOException {
String pathString = (args.size() < 2) ? Path.CUR_DIR : args.removeLast();
try {
dst = new PathData(new URI(pathString), getConf());
} catch (URISyntaxException e) {
if (Path.WINDOWS) {
// Unlike URI, PathData knows how to parse Windows drive-letter paths.
dst = new PathData(pathString, getConf());
} else {
throw new IOException("unexpected URISyntaxException", e);
}
}
}
/**
* The last arg is expected to be a remote path, if only one argument is
* given then the destination will be the remote user's directory
* @param args is the list of arguments
* @throws PathIOException if path doesn't exist or matches too many times
*/
protected void getRemoteDestination(LinkedList<String> args)
throws IOException {
if (args.size() < 2) {
dst = new PathData(Path.CUR_DIR, getConf());
} else {
String pathString = args.removeLast();
// if the path is a glob, then it must match one and only one path
PathData[] items = PathData.expandAsGlob(pathString, getConf());View on GitHub (pinned to 2add963021)
Solutions
- On Linux/MacOS use a plain POSIX destination path (e.g. /tmp/out) instead of a Windows drive-letter path
- Remove URI-illegal characters (spaces, backslashes, reserved symbols) from the local destination name
- Verify the destination parses first with new URI(destString) or use a destination directory that already exists and keep the generated filename simple
Example fix
# before (on Linux) hdfs dfs -get /data/part-00000 C:\tmp\part-00000 # after hdfs dfs -get /data/part-00000 /tmp/part-00000
Defensive patterns
Strategy: try-catch
Validate before calling
// pre-validate a local destination string the same way the shell will
try {
new java.net.URI(dest);
} catch (java.net.URISyntaxException e) {
if (!org.apache.hadoop.fs.Path.WINDOWS) {
throw new IllegalArgumentException("Local destination is not URI-safe on this OS: " + dest, e);
}
} Try / catch
try {
shellRun("-get", src, localDest);
} catch (IOException e) {
if (e.getMessage() != null && e.getMessage().contains("unexpected URISyntaxException")) {
// local destination had URI-illegal chars (e.g. Windows drive path on Linux); sanitize and retry once
shellRun("-get", src, sanitize(localDest));
} else throw e;
} Prevention
- Use plain POSIX destination paths on Linux/MacOS; drive-letter paths only parse on Windows hosts
- Keep local destination filenames free of spaces and URI-reserved characters
- Centralize destination construction in one helper that runs the URI pre-check above
When it happens
Trigger: 'hdfs dfs -get /data/file C:\tmp\out' executed on Linux (the C: drive-letter form only parses on Windows); a local destination containing a space like './my file.txt'; brackets, pipes, or other reserved characters in the local path.
Common situations: Runbooks written on Windows executed verbatim on Linux gateways; localization where paths contain spaces; automation copying the HDFS side of the command but hand-typing a local target with illegal characters.
Related errors
- Bad configuration of hadoop.security.key.provider.path at ${
- Illegal option {}
- Not enough arguments: expected {} but got {}
- Too many arguments: expected {} but got {}
- No attribute for {}
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/676cdd82c587a548.
Report an issue: GitHub.