apache/hadoop · error · IllegalArgumentException
Invalid specification for distributed-cache artifacts of typ
Error message
Invalid specification for distributed-cache artifacts of type {} : #uris={} #timestamps={} #visibilities={} What it means
When a job is submitted, LocalResourceBuilder.createLocalResources turns the distributed-cache artifacts of one type (files, archives, libjars) into LocalResources using four parallel arrays populated from job conf keys: uris, timestamps, sizes, visibilities. If the arrays have different lengths the artifacts cannot be paired 1:1, so it fails fast with IllegalArgumentException naming the type and each count. These keys are normally filled in atomically by the submission API; mismatch means someone wrote them by hand or partially overwrote them.
Source
Thrown at hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-common/src/main/java/org/apache/hadoop/mapreduce/v2/util/LocalResourceBuilder.java:96
this.sizes = s;
}
void setVisibilities(boolean[] v) {
this.visibilities = v;
}
void setSharedCacheUploadPolicies(Map<String, Boolean> policies) {
this.sharedCacheUploadPolicies = policies;
}
void createLocalResources(Map<String, LocalResource> localResources)
throws IOException {
if (uris != null) {
// Sanity check
if ((uris.length != timestamps.length) || (uris.length != sizes.length) ||
(uris.length != visibilities.length)) {
throw new IllegalArgumentException("Invalid specification for " +
"distributed-cache artifacts of type " + type + " :" +
" #uris=" + uris.length +
" #timestamps=" + timestamps.length +
" #visibilities=" + visibilities.length
);
}
for (int i = 0; i < uris.length; ++i) {
URI u = uris[i];
Path p = new Path(u);
FileSystem remoteFS = p.getFileSystem(conf);
String linkName = null;
if (p.getName().equals(DistributedCache.WILDCARD)) {
p = p.getParent();
linkName = p.getName() + Path.SEPARATOR + DistributedCache.WILDCARD;
}
View on GitHub (pinned to 2add963021)
Solutions
- Use the public API (job.addCacheFile / addArchiveToClassPath / DistributedCache) instead of raw conf keys — it regenerates all four arrays consistently
- If raw keys are unavoidable, always write the four keys together with identical element counts (clearing stale ones first)
- Rebuild the job conf from a clean Job.getInstance instead of mutating a previously submitted conf
Example fix
// before (manual, mismatch-prone)
conf.setStrings("mapreduce.job.cache.files", "hdfs://nn/a.jar,hdfs://nn/b.jar");
// mapreduce.job.cache.files.timestamps etc. left from a previous 1-file config -> throws
// after
Job job = Job.getInstance(conf);
job.addCacheFile(new URI("hdfs://nn/a.jar"));
job.addCacheFile(new URI("hdfs://nn/b.jar")); // submitter fills timestamps/sizes/visibilities Defensive patterns
Strategy: validation
Validate before calling
String[] uris = conf.getStrings("mapreduce.job.cache.files");
long[] ts = conf.getLongs("mapreduce.job.cache.files.timestamps");
long[] sz = conf.getLongs("mapreduce.job.cache.files.sizes");
boolean[] vis = parseVisibilities(conf); // same companion key
if (uris != null && (ts == null || sz == null || vis == null
|| uris.length != ts.length || uris.length != sz.length
|| uris.length != vis.length)) {
throw new IOException("Distributed cache arrays out of sync — regenerate via job.addCacheFile");
} Try / catch
try {
job.submit();
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("distributed-cache artifacts")) {
// clear all four companion keys and re-add cache entries via the Job API
}
throw e;
} Prevention
- Never hand-write the cache .files/.timestamps/.sizes/.visibilities keys — use job.addCacheFile/addArchiveToClassPath
- Start from a fresh Job.getInstance(conf) per submission instead of reusing submitted confs
- Add a conf lint that asserts equal lengths of the four cache arrays before submit
When it happens
Trigger: Setting conf keys like mapreduce.job.cache.files (or .archives / .libjars and their .timestamps/.sizes/.visibilities companions) directly with unequal counts; hand-editing a serialized job conf; copying only some of the four keys between configurations.
Common situations: Custom submission frameworks (Spark/Cascading-style) that manipulate the raw cache conf keys instead of the Job API; reusing an old conf object where files were appended but metadata arrays were not regenerated; XML conf templates that define only the files key.
Related errors
- Resource name must be relative
- Invalid path URI: {} - cannot contain both a URI fragment an
- Unable to parse '{}' as a URI, check the setting for mapredu
- Could not locate MapReduce framework name '{}' in mapreduce.
- Invalid path URI: {} - cannot contain both a URI fragment an
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/242a45037b8f4243.
Report an issue: GitHub.