apache/hadoop · critical · InvalidObjectException
No URI in deserialized Path
Error message
No URI in deserialized Path
What it means
Path implements ObjectInputValidation and its validateObject() runs after Java native deserialization; if the uri field is null it throws InvalidObjectException. This guard exists to defend against malicious or corrupted object streams: Path's invariants (a non-null URI) must hold even when the object did not come from a constructor. Seeing it means the serialized stream was tampered with, truncated, written by incompatible code, or the field was never set.
Source
Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/Path.java:615
URI newUri = null;
try {
newUri = new URI(scheme, authority ,
normalizePath(scheme, pathUri.getPath()), null, fragment);
} catch (URISyntaxException e) {
throw new IllegalArgumentException(e);
}
return new Path(newUri);
}
/**
* Validate the contents of a deserialized Path, so as
* to defend against malicious object streams.
* @throws InvalidObjectException if there's no URI
*/
@Override
public void validateObject() throws InvalidObjectException {
if (uri == null) {
throw new InvalidObjectException("No URI in deserialized Path");
}
}
}
View on GitHub (pinned to 2add963021)
Solutions
- Verify integrity of the serialized payload: re-transfer or regenerate the stream and confirm it was produced by the same Hadoop version on both ends.
- Prefer rebuilding the object: serialize the path String (path.toUri().toString()) and reconstruct with new Path(str) instead of Java object serialization of Path itself.
- If streams come from an untrusted source, validate before deserializing and treat InvalidObjectException as a security signal, not a retryable glitch.
- Align Hadoop versions on writer and reader so serialized class layouts match.
Example fix
// before Path p = (Path) in.readObject(); // may yield InvalidObjectException on bad streams // after // send/receive the textual form instead of the Java object writeUTF(p.toUri().toString()); ... Path p = new Path(in.readUTF());
Defensive patterns
Strategy: validation
Validate before calling
// validate after deserialization instead of trusting the stream
Object o = in.readObject();
if (o instanceof Path) {
Path p = (Path) o;
if (p.toUri() == null) {
throw new InvalidObjectException("Path without URI");
}
} Try / catch
try {
Path p = (Path) in.readObject(); // validateObject() runs here
} catch (InvalidObjectException e) {
// treat as corrupt/hostile stream: discard, do not retry
throw new IOException("Corrupt serialized Path payload", e);
} Prevention
- Serialize Path as its URI string, not as a Java object.
- Treat InvalidObjectException as a data-integrity/security signal, not transient.
- Pin matching Hadoop versions on both ends of any object-stream channel carrying Paths.
When it happens
Trigger: ObjectInputStream.readObject() on a stream containing a Path whose uri field is absent/null, deserializing Paths written by a differently-versioned Hadoop or hand-crafted streams, or interposing a readObject that leaves uri unset.
Common situations: RPC or MapReduce shuffle payloads deserialized after partial writes, caches (e.g. persisted DistCp/CopyFiles FilePair sequences) moved between Hadoop versions, cross-service serialization where one side serialized a Path subclass without a URI, or security testing with mutated streams.
Related errors
- encoded array component type {} is not a candidate primitive
- encoded array length is negative {}
- Encoded type {} converted to valid component type {} but no
- Cannot initialize the class: {clazz}
- parent + " is a file"
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/9bbab61ef863a7ae.
Report an issue: GitHub.