{"record":{"id":"0c8b02b1ccab5d28","repo":"apache/hadoop","slug":"invalid-path-uri-cannot-contain-both-a-uri-f","errorCode":null,"errorMessage":"Invalid path URI: {} - cannot contain both a URI fragment and a wildcard","messagePattern":"Invalid path URI: (.+?) - cannot contain both a URI fragment and a wildcard","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-common/src/main/java/org/apache/hadoop/mapreduce/v2/util/LocalResourceBuilder.java","lineNumber":135,"sourceCode":"\n        // If there's no wildcard, try using the fragment for the link\n        if (linkName == null) {\n          linkName = u.getFragment();\n\n          // Because we don't know what's in the fragment, we have to handle\n          // it with care.\n          if (linkName != null) {\n            Path linkPath = new Path(linkName);\n\n            if (linkPath.isAbsolute()) {\n              throw new IllegalArgumentException(\"Resource name must be \"\n                  + \"relative\");\n            }\n\n            linkName = linkPath.toUri().getPath();\n          }\n        } else if (u.getFragment() != null) {\n          throw new IllegalArgumentException(\"Invalid path URI: \" + p +\n              \" - cannot contain both a URI fragment and a wildcard\");\n        }\n\n        // If there's no wildcard or fragment, just link to the file name\n        if (linkName == null) {\n          linkName = p.getName();\n        }\n\n        LocalResource orig = localResources.get(linkName);\n        if(orig != null && !orig.getResource().equals(URL.fromURI(p.toUri()))) {\n          LOG.warn(getResourceDescription(orig.getType()) + orig.getResource()\n              + \" conflicts with \" + getResourceDescription(type) + u);\n          continue;\n        }\n        Boolean sharedCachePolicy = sharedCacheUploadPolicies.get(u.toString());\n        sharedCachePolicy =\n            sharedCachePolicy == null ? Boolean.FALSE : sharedCachePolicy;\n        localResources.put(linkName, LocalResource.newInstance(URL.fromURI(p","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-common/src/main/java/org/apache/hadoop/mapreduce/v2/util/LocalResourceBuilder.java#L117-L153","documentation":"LocalResourceBuilder.createLocalResources rejects cache URIs that combine a wildcard path ('dir/*') with a URI fragment ('#name'): the wildcard case resolves the parent directory and derives link names from actual file names, while the fragment names exactly one link — the two mechanisms are mutually exclusive, so the builder throws IllegalArgumentException. The fragment is only honored for non-wildcard entries.","triggerScenarios":"A distributed-cache entry like 'hdfs://nn/jars/*#myjars' (or '#myjars.jar') set via job.addCacheFile, DistributedCache.addCacheFile, or the mapreduce.job.cache.files conf key.","commonSituations":"Trying to name a whole directory of jars with one symlink; copy-pasting a single-file fragment pattern onto a wildcard entry; generated job configs that concatenate a fragment onto every cache URI.","solutions":["Use the wildcard alone ('hdfs://nn/jars/*') — each file gets its own link named after the file","Or point at the specific file with the fragment ('hdfs://nn/jars/one.jar#one.jar')","Strip fragments from wildcard entries in whatever generates your cache configuration"],"exampleFix":"# before\nmapreduce.job.cache.files = hdfs://nn/jars/*#myjars   # throws\n\n# after (choose one)\nmapreduce.job.cache.files = hdfs://nn/jars/*            # wildcard: per-file default names\n# or\nmapreduce.job.cache.files = hdfs://nn/jars/one.jar#one.jar  # explicit file + fragment","handlingStrategy":"validation","validationCode":"static boolean isValidCacheUri(URI u) {\n  Path p = new Path(u);\n  boolean wildcard = p.getName().equals(DistributedCache.WILDCARD);\n  return !(wildcard && u.getFragment() != null);\n}\nfor (URI u : cacheUris) { if (!isValidCacheUri(u)) throw new IOException(\"wildcard+fragment: \" + u); }","typeGuard":null,"tryCatchPattern":"try {\n  job.addCacheFile(u);\n} catch (IllegalArgumentException e) {\n  if (u.getFragment() != null && u.toString().contains(\"*\")) {\n    job.addCacheFile(UriBuilder.fromUri(u).fragment(null).build()); // drop fragment\n  } else throw e;\n}","preventionTips":["Keep one convention: wildcards for directories, fragments for single files","Reject cache URIs containing both '*' and '#' in config validation"],"tags":["hadoop","mapreduce","distributed-cache","wildcard","uri","fragment"],"backgroundTag":"invalid-distributed-cache-uri","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}