apache/hadoop · error · IllegalArgumentException
Identifier '${identifier}' does not exist in RefreshRegistry
Error message
Identifier '${identifier}' does not exist in RefreshRegistry. Valid options are: ${validOptions} What it means
RefreshRegistry.dispatch looks up handlers by identifier in a Guava Multimap; when no handler is registered it throws IllegalArgumentException listing every registered identifier as 'Valid options'. It is how refresh requests (dfsadmin/rmadmin '-refresh...' style flows over the admin protocol) reject an unknown resource name. Note the registry is a JVM-global singleton, so validity depends on what that process registered.
Source
Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/RefreshRegistry.java:102
}
/**
* Lookup the responsible handler and return its result.
* This should be called by the RPC server when it gets a refresh request.
* @param identifier the resource to refresh
* @param args the arguments to pass on, not including the program name
* @throws IllegalArgumentException on invalid identifier
* @return the response from the appropriate handler
*/
public synchronized Collection<RefreshResponse> dispatch(String identifier, String[] args) {
Collection<RefreshHandler> handlers = handlerTable.get(identifier);
if (handlers.size() == 0) {
String msg = "Identifier '" + identifier +
"' does not exist in RefreshRegistry. Valid options are: " +
Joiner.on(", ").join(handlerTable.keySet());
throw new IllegalArgumentException(msg);
}
ArrayList<RefreshResponse> responses =
new ArrayList<RefreshResponse>(handlers.size());
// Dispatch to each handler and store response
for(RefreshHandler handler : handlers) {
RefreshResponse response;
// Run the handler
try {
response = handler.handleRefresh(identifier, args);
if (response == null) {
throw new NullPointerException("Handler returned null.");
}
LOG.info(handlerName(handler) + " responds to '" + identifier +
"', says: '" + response.getMessage() + "', returns " +View on GitHub (pinned to 2add963021)
Solutions
- Use one of the valid options printed in the message itself — they are the registered identifiers of the target process.
- Register the handler server-side with the exact identifier the admin client sends; matching is exact string comparison.
- For custom refreshables, share the identifier as a constant between registration code and client invocation code so the two can never drift.
Example fix
// before String id = readFromConfig(); // "MyPlugin" — not registered anywhere RefreshRegistry.defaultRegistry().dispatch(id, args); // IllegalArgumentException // after // server init: RefreshRegistry.defaultRegistry().register(MyPlugin.REFRESH_ID, handler); RefreshRegistry.defaultRegistry().dispatch(MyPlugin.REFRESH_ID, args); // exact same constant
Defensive patterns
Strategy: validation
Validate before calling
// share one constant between registration and dispatch so they cannot drift
public static final String REFRESH_ID = "com.example.myplugin";
// server init:
RefreshRegistry.defaultRegistry().register(REFRESH_ID, handler);
// client / test, before dispatch:
if (!REFRESH_ID.equals(requestedId)) {
throw new IllegalArgumentException(
"unknown refresh id '" + requestedId + "', expected " + REFRESH_ID);
}
RefreshRegistry.defaultRegistry().dispatch(requestedId, args); Try / catch
Catch IllegalArgumentException around dispatch and surface its message to the operator — the 'Valid options are:' list is the authoritative set of registered identifiers for that process.
Prevention
- Define the identifier once as a shared constant used by both server registration and client invocation.
- Confirm the target daemon actually registers the refreshable before exposing the admin command.
- Remember the registry is per-JVM: an identifier valid on the NameNode may not exist on another daemon.
When it happens
Trigger: Dispatching a refresh whose identifier differs from any registered handler: a typo, different casing, an identifier registered in a different daemon, or a handler never registered because the feature is not loaded. Because handlerTable is a Multimap keyed by exact string, only an exact match dispatches.
Common situations: Running a refresh command against a service that does not support it (e.g., user-to-group mapping refresh on a daemon that never registered it); custom refreshables where client and server disagree on the identifier string; version differences changing which refreshables exist.
Related errors
- Identifier cannot be null
- Handler returned null.
- Unable to refresh queues because queue-hierarchy changed. Re
- Request must contain identifier
- %s is not available
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/29ce3a0c6e2260ed.
Report an issue: GitHub.