apache/hadoop · error · HadoopIllegalArgumentException

Cannot close proxy since it is null

Error message

Cannot close proxy since it is null

What it means

RPC.stopProxy(null) throws HadoopIllegalArgumentException immediately. The API deliberately refuses null so that lost or never-created proxy references surface as bugs at the call site instead of no-op cleanup. Hitting it means your code attempted to stop a proxy that was never created or whose reference was already cleared.

Source

Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/RPC.java:797

    throws IOException {

    return getProtocolProxy(protocol, clientVersion, addr, conf, NetUtils
        .getDefaultSocketFactory(conf));
  }

  /**
   * Stop the proxy. Proxy must either implement {@link Closeable} or must have
   * associated {@link RpcInvocationHandler}.
   * 
   * @param proxy
   *          the RPC proxy object to be stopped
   * @throws HadoopIllegalArgumentException
   *           if the proxy does not implement {@link Closeable} interface or
   *           does not have closeable {@link InvocationHandler}
   */
  public static void stopProxy(Object proxy) {
    if (proxy == null) {
      throw new HadoopIllegalArgumentException(
          "Cannot close proxy since it is null");
    }
    try {
      if (proxy instanceof Closeable) {
        ((Closeable) proxy).close();
        return;
      } else {
        InvocationHandler handler = Proxy.getInvocationHandler(proxy);
        if (handler instanceof Closeable) {
          ((Closeable) handler).close();
          return;
        }
      }
    } catch (IOException e) {
      LOG.error("Closing proxy or invocation handler caused exception", e);
    } catch (IllegalArgumentException e) {
      LOG.error("RPC.stopProxy called on non proxy: class=" + proxy.getClass().getName(), e);
    }

View on GitHub (pinned to 2add963021)

Solutions

  1. Null-guard the call: if (proxy != null) { RPC.stopProxy(proxy); proxy = null; }
  2. Ensure stopProxy only runs on paths where assignment succeeded, e.g., track a 'created' flag or assign the field only inside the try after success.
  3. Centralize creation and cleanup in one owner class so the proxy is stopped exactly once from exactly one place.

Example fix

// before
MyProto proxy = null;
try {
  proxy = RPC.getProxy(...);
  use(proxy);
} finally {
  RPC.stopProxy(proxy); // throws if getProxy failed
}
// after
MyProto proxy = null;
try {
  proxy = RPC.getProxy(...);
  use(proxy);
} finally {
  if (proxy != null) {
    RPC.stopProxy(proxy);
    proxy = null;
  }
}
Defensive patterns

Strategy: validation

Validate before calling

if (proxy == null) {
  LOG.debug("no proxy to stop");
} else {
  RPC.stopProxy(proxy);
  proxy = null;
}

Prevention

When it happens

Trigger: Calling RPC.stopProxy(proxy) in a finally block when proxy creation threw earlier and the field stayed null; double-cleanup paths that null the field after the first stop; utility code that closes whatever it is handed, including null.

Common situations: Connection failure in try/finally cleanup; refactors that moved proxy assignment after an exception-throwing step; guard code written for one path reused on a path where creation never happened.

Related errors


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