{"record":{"id":"00e777f690aa4407","repo":"apache/hadoop","slug":"interrupted-while-copying-objects-copy","errorCode":null,"errorMessage":"Interrupted while copying objects (copy)","messagePattern":"Interrupted while copying objects \\(copy\\)","errorType":"exception","errorClass":"InterruptedIOException","httpStatus":null,"severity":"error","filePath":"hadoop-cloud-storage-project/hadoop-huaweicloud/src/main/java/org/apache/hadoop/fs/obs/OBSObjectBucketUtils.java","lineNumber":376,"sourceCode":"              + srcKey\n              + \", dst=\"\n              + dstKey\n              + \", delay=\"\n              + delay\n              + \"}\");\n    }\n  }\n\n  private static void waitAllCopyFinished(\n      final List<Future<CopyObjectResult>> copyFutures)\n      throws IOException {\n    try {\n      for (Future<CopyObjectResult> copyFuture : copyFutures) {\n        copyFuture.get();\n      }\n    } catch (InterruptedException e) {\n      LOG.warn(\"Interrupted while copying objects (copy)\");\n      throw new InterruptedIOException(\n          \"Interrupted while copying objects (copy)\");\n    } catch (ExecutionException e) {\n      for (Future<CopyObjectResult> future : copyFutures) {\n        future.cancel(true);\n      }\n\n      throw OBSCommonUtils.extractException(\n          \"waitAllCopyFinished\", copyFutures.toString(), e);\n    }\n  }\n\n  /**\n   * Request object metadata; increments counters in the process.\n   *\n   * @param owner OBS File System instance\n   * @param key   key\n   * @return the metadata\n   */","sourceCodeStart":358,"sourceCodeEnd":394,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-cloud-storage-project/hadoop-huaweicloud/src/main/java/org/apache/hadoop/fs/obs/OBSObjectBucketUtils.java#L358-L394","documentation":"During an object-bucket rename, each source object is copied by a task submitted to a thread pool; waitAllCopyFinished blocks on every Future. If the waiting thread is interrupted, the code logs a warning and throws InterruptedIOException('Interrupted while copying objects (copy)'). The rename stops mid-way, so some destination objects may already exist while the source is still intact.","triggerScenarios":"The thread running FileSystem.rename is interrupted: YARN or Spark cancels the task (speculative execution, preemption), executor shutdownNow(), a wrapping Future.cancel(true), or a caller timeout that aborts the operation.","commonSituations":"Speculative tasks cancelled mid-commit; user cancels a long job moving a large directory; frameworks with hard per-task timeouts interrupting a big copy phase; shutdown hooks racing in-flight renames.","solutions":["Do not interrupt the worker thread: cancel jobs only at safe points, or let the rename finish","Catch InterruptedIOException, restore the interrupt flag with Thread.currentThread().interrupt(), clean the partial destination, and re-run the rename","Split very large directory moves into smaller subtrees so a timeout is less likely to fire mid-copy"],"exampleFix":"// before\nFuture<?> f = pool.submit(() -> fs.rename(src, dst));\nf.get(1, TimeUnit.SECONDS); // timeout -> cancel(true) -> InterruptedIOException\n\n// after\nFuture<?> f = pool.submit(() -> fs.rename(src, dst));\nf.get(); // let the copy finish; interrupt only on shutdown\n\n// recovery path\ntry {\n  fs.rename(src, dst);\n} catch (InterruptedIOException e) {\n  Thread.currentThread().interrupt();\n  fs.delete(dst, true);\n  fs.rename(src, dst); // re-run after cleanup\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  fs.rename(src, dst);\n} catch (InterruptedIOException e) {\n  Thread.currentThread().interrupt(); // restore the flag\n  fs.delete(dst, true);              // remove partial copies\n  fs.rename(src, dst);               // re-run: source is still intact\n}","preventionTips":["Never interrupt threads performing large renames; cancel at commit boundaries","Keep caller timeouts generous for directory-sized copies","Split large directory moves into smaller subtree renames","Log rename durations so timeouts can be sized from data"],"tags":["hadoop","obs","rename","interrupt","concurrency"],"backgroundTag":"operation-interrupted","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}