apache/hadoop · error · IOException
wrong key class: {} is not {}
Error message
wrong key class: {} is not {} What it means
Writer.append(Object key, Object val) enforces that key's runtime class is exactly (==, not instanceof) the declared keyClass before serializing; a mismatch throws this IOException naming both classes. Mixing classes would desynchronize the record format since the serializer was built for one specific class, so the writer fails fast instead of producing garbage.
Source
Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/SequenceFile.java:1473
* @param val input Writable val.
* @throws IOException raised on errors performing I/O.
*/
public void append(Writable key, Writable val)
throws IOException {
append((Object) key, (Object) val);
}
/**
* Append a key/value pair.
* @param key input Object key.
* @param val input Object val.
* @throws IOException raised on errors performing I/O.
*/
@SuppressWarnings("unchecked")
public synchronized void append(Object key, Object val)
throws IOException {
if (key.getClass() != keyClass)
throw new IOException("wrong key class: "+key.getClass().getName()
+" is not "+keyClass);
if (val.getClass() != valClass)
throw new IOException("wrong value class: "+val.getClass().getName()
+" is not "+valClass);
buffer.reset();
// Append the 'key'
keySerializer.serialize(key);
int keyLength = buffer.getLength();
if (keyLength < 0)
throw new IOException("negative length keys not allowed: " + key);
// Append the 'value'
if (compress == CompressionType.RECORD) {
deflateFilter.resetState();
compressedValSerializer.serialize(val);
deflateOut.flush();View on GitHub (pinned to 2add963021)
Solutions
- Align Writer.keyClass(...) with the concrete class actually appended
- If you hold a subclass, copy its fields into an instance of the exact declared class before append
- Guard with key.getClass() == writer.getKeyClass() before appending (exact check, matching the writer's semantics)
Example fix
// before
Writer w = SequenceFile.createWriter(conf, Writer.file(p),
Writer.keyClass(LongWritable.class), Writer.valueClass(Text.class));
w.append(new Text("oops"), new Text("v")); // wrong key class: Text is not LongWritable
// after
w.append(new LongWritable(42), new Text("v")); Defensive patterns
Strategy: type-guard
Validate before calling
if (key.getClass() != w.getKeyClass()) {
throw new IllegalArgumentException("key " + key.getClass() + " != declared " + w.getKeyClass());
} Type guard
static boolean isExactKeyClass(SequenceFile.Writer w, Object key) {
return key != null && key.getClass() == w.getKeyClass();
} Try / catch
try {
w.append(key, val);
} catch (IOException e) {
if (e.getMessage() != null && e.getMessage().startsWith("wrong key class")) {
// record type drift: align writer options or convert the record, then retry
} else { throw e; }
} Prevention
- Create the writer with keyClass/valueClass from the same constants used to type the records
- In generic code, guard with getClass() == writer.getKeyClass() (exact match, not instanceof, mirroring the writer's semantics)
When it happens
Trigger: writer.append(new Text("x"), v) on a writer built with Writer.keyClass(LongWritable.class); appending a subclass instance (MyText extends Text) where the header stores Text; call sites whose static types were refactored while the writer options were not.
Common situations: keyClass/valueClass options drifting from the appended records during refactors; erased generics hiding mismatches until runtime; reusable record objects of the wrong concrete type passed from a shared loop.
Related errors
- wrong value class: {} is not {}
- Key/value class provided does not match the file
- A record version mismatch occurred. Expecting v{}, found v{}
- Compression option provided does not match the file
- negative length keys not allowed: {}
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/995ff846de5b7af2.
Report an issue: GitHub.