{"record":{"id":"3b7414df8bd2a979","repo":"apache/druid","slug":"interrupted-while-waiting-for-mount","errorCode":null,"errorMessage":"Interrupted while waiting for mount","messagePattern":"Interrupted while waiting for mount","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"warning","filePath":"server/src/main/java/org/apache/druid/segment/loading/PartialSegmentBundleCacheEntry.java","lineNumber":677,"sourceCode":"    }\n    final Set<String> present = bundleNames(fileMapper);\n    // legacy v10 segments from before bundle field was persisted in the segment\n    if (present.size() == 1 && present.contains(SegmentFileBuilder.ROOT_BUNDLE_NAME)) {\n      return SegmentFileBuilder.ROOT_BUNDLE_NAME;\n    }\n    // Requested bundle is absent and there are named bundles present: leave the name as-is so the caller fails\n    // loudly (forBundle throws \"no containers\") rather than silently serving the wrong data.\n    return requestedBundleName;\n  }\n\n  private static void awaitMount(SettableFuture<Void> future) throws IOException\n  {\n    try {\n      future.get();\n    }\n    catch (InterruptedException e) {\n      Thread.currentThread().interrupt();\n      throw new IOException(\"Interrupted while waiting for mount\", e);\n    }\n    catch (ExecutionException e) {\n      final Throwable cause = e.getCause() == null ? e : e.getCause();\n      switch (cause) {\n        case IOException ioException -> throw ioException;\n        case RuntimeException runtimeException -> throw runtimeException;\n        case Error error -> throw error;\n        default -> throw DruidException.defensive(e, \"mount failed\");\n      }\n    }\n  }\n\n  private static void releaseHolds(Collection<StorageLocation.ReservationHold<?>> holds)\n  {\n    for (StorageLocation.ReservationHold<?> hold : holds) {\n      try {\n        hold.close();\n      }","sourceCodeStart":659,"sourceCodeEnd":695,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/server/src/main/java/org/apache/druid/segment/loading/PartialSegmentBundleCacheEntry.java#L659-L695","documentation":"PartialSegmentBundleCacheEntry.awaitMount blocks on the Future produced by the asynchronous mount operation. If the waiting thread is interrupted, it restores the interrupt flag and wraps the InterruptedException in an IOException to signal that the mount result could not be observed.","triggerScenarios":"A thread calling mount() on a PartialSegmentBundleCacheEntry is interrupted (Thread.interrupt()) while blocked in future.get() waiting for the async mount to complete.","commonSituations":"Historical server shutdown or segment-drop racing with an in-flight partial mount; query/ingestion threads cancelled while waiting for lazy segment loading; executor shutdown during reload.","solutions":["Retain the interrupt status (the code already does Thread.currentThread().interrupt()) and let shutdown proceed; retry the segment load after the node is healthy.","Avoid interrupting load threads during normal operation; ensure graceful shutdown waits for pending mounts.","Check for overly aggressive cancellation in code that calls loadSegment or mount paths."],"exampleFix":"// before\ntry { entry.mount(location); } catch (IOException e) { LOGGER.warn(e, \"mount failed\"); }\n// after\ntry { entry.mount(location); }\ncatch (IOException e) {\n  if (Thread.currentThread().isInterrupted()) { /* interrupted during mount; back off and retry */ }\n  else { LOGGER.warn(e, \"mount failed\"); }\n}","handlingStrategy":"try-catch","validationCode":"if (Thread.currentThread().isInterrupted()) {\n  // avoid starting a blocking mount wait on an already-interrupted thread\n  throw new InterruptedException();\n}","typeGuard":null,"tryCatchPattern":"try {\n  entry.mount(location);\n} catch (IOException e) {\n  if (e.getCause() instanceof InterruptedException || Thread.currentThread().isInterrupted()) {\n    Thread.currentThread().interrupt(); // preserve flag; abandon this mount, coordinator will retry\n    return;\n  }\n  throw e;\n}","preventionTips":["Don't interrupt load/reload threads except during shutdown.","Use graceful shutdown that drains pending segment mounts.","Avoid long-lived blocking waits racing with segment drops.","Retry segment loads after interruption; mounts are idempotent."],"tags":["interruption","threading","segment-mount","cache"],"backgroundTag":"operation-interrupted","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}