{"record":{"id":"bb29200ac66506f2","repo":"apache/hadoop","slug":"call-interrupted","errorCode":null,"errorMessage":"Call interrupted","messagePattern":"Call interrupted","errorType":"exception","errorClass":"InterruptedIOException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/Client.java","lineNumber":1600,"sourceCode":"  }\n\n  private void releaseAsyncCall() {\n    asyncCallCounter.decrementAndGet();\n  }\n\n  @VisibleForTesting\n  int getAsyncCallCount() {\n    return asyncCallCounter.get();\n  }\n\n  /** @return the rpc response or, in case of timeout, null. */\n  private Writable getRpcResponse(final Call call, final Connection connection)\n      throws IOException {\n    try {\n      return call.rpcResponseFuture.get();\n    } catch (InterruptedException ie) {\n      Thread.currentThread().interrupt();\n      throw new InterruptedIOException(\"Call interrupted\");\n    } catch (ExecutionException e) {\n      Throwable cause = e.getCause();\n      if (cause instanceof IOException) {\n        throw warpIOException((IOException) cause, connection);\n      }\n      throw new IllegalStateException(e);\n    }\n  }\n\n  private IOException warpIOException(IOException ioe, Connection connection) {\n    if (ioe instanceof RemoteException ||\n        ioe instanceof SaslException) {\n      ioe.fillInStackTrace();\n      return ioe;\n    } else { // local exception\n      InetSocketAddress address = connection.getRemoteAddress();\n      return NetUtils.wrapException(address.getHostName(),\n          address.getPort(),","sourceCodeStart":1582,"sourceCodeEnd":1618,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/Client.java#L1582-L1618","documentation":"Thrown as an InterruptedIOException when the thread waiting for an Hadoop IPC response is interrupted while blocked in Call.rpcResponseFuture.get() inside Client.getRpcResponse. The client deliberately re-sets the thread's interrupt flag (Thread.currentThread().interrupt()) before throwing, so the interruption is not lost. It almost always means application shutdown, executor shutdownNow(), or a timeout framework cancelled the calling thread mid-RPC, not an RPC failure itself.","triggerScenarios":"Calling a blocking RPC proxy method on a thread that gets interrupted: submit RPC work to an ExecutorService and call shutdownNow(); a watchdog/timeout thread interrupts the RPC caller; JVM shutdown hooks interrupt in-flight calls; test frameworks (JUnit timeout, Thread.interrupt() in @After) cancel the RPC thread.","commonSituations":"MapReduce/YARN task cancellation interrupting client threads, graceful application shutdown racing in-flight NameNode/ResourceManager calls, retry frameworks that interrupt the previous attempt, unit tests with aggressive thread cleanup.","solutions":["Catch InterruptedIOException and treat it as cancellation: restore the interrupt flag (it is already restored by the client) and stop the loop/task instead of retrying the RPC.","If interrupts are unexpected, find who calls Thread.interrupt()/ExecutorService.shutdownNow() on the RPC thread (jstack shows the blocked worker) and stop that path before shutdown completes.","Do not retry the same call on the same interrupted thread; move new calls to a non-interrupted thread if you must re-issue them."],"exampleFix":"// before\ntry {\n FsStatus s = fs.getStatus(); // blocking RPC on an interruptible thread\n} catch (IOException e) {\n LOG.error(\"RPC failed\", e); // wrongly treats cancellation as failure and retries\n}\n\n// after\ntry {\n FsStatus s = fs.getStatus();\n} catch (InterruptedIOException e) {\n // thread is already re-interrupted by the client; just stop working\n LOG.info(\"RPC cancelled by thread interruption; aborting task\");\n return;\n} catch (IOException e) {\n LOG.error(\"RPC failed\", e);\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  T result = proxy.rpcCall(req);\n} catch (InterruptedIOException e) {\n  // interrupt flag was already restored by Client.getRpcResponse\n  LOG.info(\"RPC cancelled by interruption; stopping task\");\n  return; // do not retry on this thread\n}","preventionTips":["Never share a thread between interruptible supervision (timeouts, shutdownNow) and unchecked blocking RPCs; isolate RPC calls in owned worker threads.","Design shutdown hooks to drain/join RPC workers before interrupting them.","Treat InterruptedIOException as cancellation, never as a retryable RPC failure."],"tags":["hadoop","ipc","rpc","interruption","concurrency","shutdown"],"backgroundTag":"thread-interruption","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}