apache/hadoop · error · IllegalArgumentException
Class {} already registered but maps to {} and not {}
Error message
Class {} already registered but maps to {} and not {} What it means
AbstractMapWritable keeps two maps (class -> byte id and id -> class). addToMap(clazz, id) throws IllegalArgumentException when the class is already registered under a different id. This happens when a Writable map's registrations are not consistent - e.g., a subclass re-registers a predefined class with a new id, or deserializing data written by a peer whose registration table differs.
Source
Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/AbstractMapWritable.java:72
@VisibleForTesting
Map<Byte, Class<?>> idToClassMap = new ConcurrentHashMap<Byte, Class<?>>();
/* The number of new classes (those not established by the constructor) */
private volatile byte newClasses = 0;
/** @return the number of known classes */
byte getNewClasses() {
return newClasses;
}
/**
* Used to add "predefined" classes and by Writable to copy "new" classes.
*/
private synchronized void addToMap(Class<?> clazz, byte id) {
if (classToIdMap.containsKey(clazz)) {
byte b = classToIdMap.get(clazz);
if (b != id) {
throw new IllegalArgumentException ("Class " + clazz.getName() +
" already registered but maps to " + b + " and not " + id);
}
}
if (idToClassMap.containsKey(id)) {
Class<?> c = idToClassMap.get(id);
if (!c.equals(clazz)) {
throw new IllegalArgumentException("Id " + id + " exists but maps to " +
c.getName() + " and not " + clazz.getName());
}
}
classToIdMap.put(clazz, id);
idToClassMap.put(id, clazz);
}
/**
* Add a Class to the maps if it is not already present.
* @param clazz clazz.
*/View on GitHub (pinned to 2add963021)
Solutions
- Register custom classes with fixed, agreed byte ids (in a static initializer or constructor) so every node computes the same table
- Never re-register the predefined classes (ids -127..-113 assigned in the AbstractMapWritable constructor) with different ids
- Ensure writers and readers run the same version of your Writable class during and after upgrades
Example fix
// before: instance-level registration, ids depend on put order
class MyMap extends MapWritable { }
// after: fixed ids, identical on every node
class MyMap extends MapWritable {
static { /* done in ctor of subclass */ }
MyMap() {
put(MyType.class, (byte) -100); // via protected addToMap(MyType.class, (byte)-100)
}
} Defensive patterns
Strategy: try-catch
Validate before calling
// deterministic registration: fixed ids in the subclass constructor
class MyMapWritable extends MapWritable {
MyMapWritable() {
addToMap(TypeA.class, (byte) -100);
addToMap(TypeB.class, (byte) -101);
}
} Try / catch
try {
map.put(key, value);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("already registered but maps to")) {
// registration tables diverged: rebuild/refresh the map instead of mixing entries
}
} Prevention
- Assign fixed byte ids to custom Writable types; never rely on first-use order
- Do not re-register predefined classes (ids -127..-113) with new ids
- Keep writers and readers on the same subclass version across a rolling upgrade
When it happens
Trigger: A custom MapWritable subclass constructor calls addToMap(MyClass.class, (byte)5) while also putting MyClass values into a map that dynamically assigns ids; readFields() on wire bytes where the sender registered the class with another id; copying between map writables with different registration histories.
Common situations: Rolling upgrades where writer and reader run different application versions with renumbered registrations; ad-hoc registration of classes in instance constructors instead of fixed static ids.
Related errors
- Id {} exists but maps to {} and not {}
- adding an additional class would exceed the maximum number a
- map cannot be copied: {}
- source map cannot be null
- Exception while get content summary
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/006c04dd69577b25.
Report an issue: GitHub.