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

  1. On Linux/MacOS use a plain POSIX destination path (e.g. /tmp/out) instead of a Windows drive-letter path
  2. Remove URI-illegal characters (spaces, backslashes, reserved symbols) from the local destination name
  3. 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

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


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/676cdd82c587a548. Report an issue: GitHub.