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

  1. Use one of the valid options printed in the message itself — they are the registered identifiers of the target process.
  2. Register the handler server-side with the exact identifier the admin client sends; matching is exact string comparison.
  3. 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

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


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/29ce3a0c6e2260ed. Report an issue: GitHub.