{"record":{"id":"997f4f26aa25ade4","repo":"apache/hadoop","slug":"error-parsing-libjars-argument-argument-must-be-a","errorCode":null,"errorMessage":"Error parsing libjars argument. Argument must be a valid URI: {}","messagePattern":"Error parsing libjars argument\\. Argument must be a valid URI: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapreduce/JobResourceUploader.java","lineNumber":297,"sourceCode":"  // Suppress warning for use of DistributedCache (it is everywhere).\n  @SuppressWarnings(\"deprecation\")\n  @VisibleForTesting\n  void uploadLibJars(Job job, Collection<String> libjars, Path submitJobDir,\n      FsPermission mapredSysPerms, short submitReplication,\n      Map<String, Boolean> fileSCUploadPolicies, Map<URI, FileStatus> statCache)\n      throws IOException {\n    Configuration conf = job.getConfiguration();\n    Path libjarsDir = JobSubmissionFiles.getJobDistCacheLibjars(submitJobDir);\n    if (!libjars.isEmpty()) {\n      mkdirs(jtFs, libjarsDir, mapredSysPerms);\n      Collection<URI> libjarURIs = new LinkedList<>();\n      boolean foundFragment = false;\n      for (String tmpjars : libjars) {\n        URI tmpURI = null;\n        try {\n          tmpURI = new URI(tmpjars);\n        } catch (URISyntaxException e) {\n          throw new IllegalArgumentException(\"Error parsing libjars argument.\"\n              + \" Argument must be a valid URI: \" + tmpjars, e);\n        }\n        Path tmp = new Path(tmpURI);\n        URI newURI = null;\n        boolean uploadToSharedCache = false;\n        boolean fromSharedCache = false;\n        if (scConfig.isSharedCacheLibjarsEnabled()) {\n          newURI = useSharedCache(tmpURI, tmp.getName(), statCache, conf, true);\n          if (newURI == null) {\n            uploadToSharedCache = true;\n          } else {\n            fromSharedCache = true;\n          }\n        }\n\n        if (newURI == null) {\n          Path newPath =\n              copyRemoteFiles(libjarsDir, tmp, conf, submitReplication);","sourceCodeStart":279,"sourceCodeEnd":315,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapreduce/JobResourceUploader.java#L279-L315","documentation":"Identical guard to the -files one, but for the -libjars option (conf 'tmpjars'): JobResourceUploader constructs java.net.URI from each libjar string before deciding whether to upload it or fetch it from the shared cache. An entry that is not a syntactically valid URI throws IllegalArgumentException('Error parsing libjars argument. Argument must be a valid URI: <entry>') with the URISyntaxException as cause.","triggerScenarios":"-libjars with an unencoded space or a Windows backslash path (C:\\m2\\repo\\...\\a.jar); classpath strings assembled by build tools that embed 'C:' plus backslashes; multiple jars separated with the wrong delimiter or containing glob characters; entries passed through several layers of shell quoting that strip characters.","commonSituations":"Windows developer machines running hadoop/sqoop/pig with -libjars; Maven/Ivy-built command lines copied into scripts; spaces in repository paths; tools forwarding user-supplied paths unchecked.","solutions":["Encode the entry or use a proper file URI: -libjars file:///C:/libs/a.jar (forward slashes, no drive-colon ambiguity)","Pre-join local paths programmatically: conf.set(\"tmpjars\", paths.stream().map(p -> new Path(p).toUri().toString()).collect(joining(\",\")))","Quote the whole -libjars value in the shell so spaces survive intact to the parser, then encode remaining illegal characters","Run a validation pass (new URI(s) per comma-separated token) before submit()"],"exampleFix":"# before\nhadoop jar app.jar Driver -libjars \"C:\\lib\\a.jar,C:\\lib\\b.jar\" in out\n# -> IllegalArgumentException: Error parsing libjars argument.\n\n# after\nhadoop jar app.jar Driver -libjars \"file:///C:/lib/a.jar,file:///C:/lib/b.jar\" in out","handlingStrategy":"validation","validationCode":"// validate/normalize every -libjars entry before submit\nList<String> safe = new ArrayList<>();\nfor (String jar : StringUtils.getStrings(conf.get(\"tmpjars\"))) {\n  try {\n    safe.add(new Path(jar).toUri().toString()); // encodes correctly\n  } catch (Exception e) {\n    throw new IllegalArgumentException(\"-libjars entry invalid: \" + jar, e);\n  }\n}\nconf.set(\"tmpjars\", String.join(\",\", safe));","typeGuard":"static boolean isValidCacheUri(String s) {\n  try { new URI(s); return true; }\n  catch (URISyntaxException e) { return false; }\n}","tryCatchPattern":null,"preventionTips":["On Windows, always use file:///C:/... forward-slash URIs for libjars","Generate libjar lists programmatically with Path.toUri(), never string concatenation","Keep dependency jars in spaces-free directories"],"tags":["distributed-cache","uri","libjars","classpath","job-submission"],"backgroundTag":"uri-parse-failed","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}