apache/hadoop · error · IllegalArgumentException
ReRegistration of rpcKind: ${rpcKind}
Error message
ReRegistration of rpcKind: ${rpcKind} What it means
Server.registerProtocolEngine maps an RPC.RpcKind to a request-wrapper class plus RpcInvoker in a static map; registering a kind that already has an entry throws IllegalArgumentException and puts the original mapping back. The framework registers its built-in kinds (RPC_BUILTIN, RPC_WRITABLE, RPC_PROTOCOL_BUFFER) once, so this error always means custom code re-registered an existing kind.
Source
Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/Server.java:297
/**
* Register a RPC kind and the class to deserialize the rpc request.
*
* Called by static initializers of rpcKind Engines
* @param rpcKind - input rpcKind.
* @param rpcRequestWrapperClass - this class is used to deserialze the
* the rpc request.
* @param rpcInvoker - use to process the calls on SS.
*/
public static void registerProtocolEngine(RPC.RpcKind rpcKind,
Class<? extends Writable> rpcRequestWrapperClass,
RpcInvoker rpcInvoker) {
RpcKindMapValue old =
rpcKindMap.put(rpcKind, new RpcKindMapValue(rpcRequestWrapperClass, rpcInvoker));
if (old != null) {
rpcKindMap.put(rpcKind, old);
throw new IllegalArgumentException("ReRegistration of rpcKind: " +
rpcKind);
}
LOG.debug("rpcKind={}, rpcRequestWrapperClass={}, rpcInvoker={}.",
rpcKind, rpcRequestWrapperClass, rpcInvoker);
}
public Class<? extends Writable> getRpcRequestWrapper(
RpcKindProto rpcKind) {
if (rpcRequestClass != null)
return rpcRequestClass;
RpcKindMapValue val = rpcKindMap.get(ProtoUtil.convert(rpcKind));
return (val == null) ? null : val.rpcRequestWrapperClass;
}
protected RpcInvoker getServerRpcInvoker(RPC.RpcKind rpcKind) {
return getRpcInvoker(rpcKind);
}
View on GitHub (pinned to 2add963021)
Solutions
- Register each RpcKind exactly once per JVM — guard with a static AtomicBoolean/set so repeated init calls are no-ops.
- Never re-register the built-in kinds; pick a genuinely distinct RPC.RpcKind for a custom engine.
- In tests, register once for the whole suite (@BeforeClass or static block) rather than per test method.
Example fix
// before
public void init() {
Server.registerProtocolEngine(MY_KIND, MyWrapper.class, myInvoker); // 2nd call throws
}
// after
private static final AtomicBoolean REGISTERED = new AtomicBoolean(false);
public void init() {
if (REGISTERED.compareAndSet(false, true)) {
Server.registerProtocolEngine(MY_KIND, MyWrapper.class, myInvoker);
}
} Defensive patterns
Strategy: validation
Validate before calling
private static final Set<RPC.RpcKind> REGISTERED_BY_ME =
ConcurrentHashMap.newKeySet();
if (REGISTERED_BY_ME.add(rpcKind)) {
Server.registerProtocolEngine(rpcKind, wrapperClass, invoker);
} Prevention
- Treat engine registration as one-time static setup, not per-instance or per-test setup.
- Never re-register the built-in RpcKinds; use a distinct kind for custom engines.
- Design tests to register once per suite and reuse servers, since the rpcKindMap is static.
When it happens
Trigger: Custom RPC engines calling registerProtocolEngine for an RpcKind already registered — including the built-in RPC_PROTOCOL_BUFFER; registration inside per-instance init or per-test setup that runs twice; static initializers re-executed via class reloading in embedded/OSGi-like containers.
Common situations: Third-party protocol-engine integrations; unit tests that construct many servers and register the engine in each setup without a guard; a plugin and service init both registering the same custom kind.
Related errors
- Unknown method {} called on {} protocol.
- Unknown protocol: {}
- Unknown method ${methodName} called on ${connectionProtocolN
- conf is not set
- protocol is not set
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/61e16e58ed89c415.
Report an issue: GitHub.