apache/hadoop · error · IOException

URI: {} is an invalid Har URI. Expecting har://<scheme>-<hos

Error message

URI: {} is an invalid Har URI. Expecting har://<scheme>-<host>/<path>.

What it means

decodeHarURI rewrites the har authority '<scheme>-<host>' into '<scheme>://<host>' via new URI(authority.replaceFirst("-", "://")) and then reassembles scheme/authority/path/fragment with the five-argument URI constructor. If either java.net.URI constructor raises URISyntaxException, it is wrapped in this IOException: the URI cannot serve as a har address.

Source

Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/HarFileSystem.java:250

      throw new IOException("URI: " + rawURI
          + " is an invalid Har URI since '-' not found."
          + "  Expecting har://<scheme>-<host>/<path>.");
    }
 
    if (rawURI.getQuery() != null) {
      // query component not allowed
      throw new IOException("query component in Path not supported  " + rawURI);
    }
 
    URI tmp;
    try {
      // convert <scheme>-<host> to <scheme>://<host>
      URI baseUri = new URI(authority.replaceFirst("-", "://"));
 
      tmp = new URI(baseUri.getScheme(), baseUri.getAuthority(),
            rawURI.getPath(), rawURI.getQuery(), rawURI.getFragment());
    } catch (URISyntaxException e) {
      throw new IOException("URI: " + rawURI
          + " is an invalid Har URI. Expecting har://<scheme>-<host>/<path>.");
    }
    return tmp;
  }

  private static String decodeString(String str)
    throws UnsupportedEncodingException {
    return URLDecoder.decode(str, "UTF-8");
  }

  private String decodeFileName(String fname)
    throws UnsupportedEncodingException {
    int version = metadata.getVersion();
    if (version == 2 || version == 3){
      return decodeString(fname);
    }
    return fname;
  }

View on GitHub (pinned to 2add963021)

Solutions

  1. Use the canonical form har://<underlying-scheme>-<host[:port]>/<archive-path>/<member>, e.g. har://hdfs-nn1:8020/user/a/data.har/f.txt
  2. Copy the exact har:// URI printed by `hadoop archive` when the archive was created instead of typing it
  3. Build the URI programmatically (new URI("har", "hdfs-nn:8020", "/user/a/data.har", null, null)) so components are validated and encoded at construction time

Example fix

// before
Path p = new Path("har://-nn:8020/user/a/data.har/f.txt"); // no scheme before '-'

// after
Path p = new Path("har://hdfs-nn:8020/user/a/data.har/f.txt");
Defensive patterns

Strategy: validation

Validate before calling

String auth = path.toUri().getAuthority();
if (auth != null && auth.indexOf('-') > 0) {
  try {
    new URI(auth.replaceFirst("-", "://")); // must parse as scheme://host
  } catch (URISyntaxException bad) {
    throw new IllegalArgumentException("Malformed har authority: " + auth, bad);
  }
} else if (auth != null) {
  throw new IllegalArgumentException("har authority must be <scheme>-<host>: " + auth);
}

Try / catch

try {
  FileSystem fs = path.getFileSystem(conf);
} catch (IOException e) {
  if (e.getMessage() != null && e.getMessage().contains("invalid Har URI")) {
    // surface as a configuration error with the expected format in the message
  }
  throw e;
}

Prevention

When it happens

Trigger: A har URI whose authority is unparseable after the dash rewrite, e.g. har://-nn:8020/x.har/f (authority '-nn:8020' becomes '://nn:8020' with no scheme), or path/fragment components containing characters the multi-argument URI constructor rejects (unencoded spaces, brackets).

Common situations: Hand-typed har:// strings with a missing scheme before the dash; URIs assembled from possibly-empty scheme/host variables in scripts; copy/paste damage of the archive URI printed by the archive tool.

Related errors


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