{"record":{"id":"eb8c6231b0689116","repo":"apache/druid","slug":"unknownfault-forexception-e","errorCode":null,"errorMessage":"UnknownFault.forException(e)","messagePattern":"UnknownFault\\.forException\\(e\\)","errorType":"error_code","errorClass":"MSQException","httpStatus":null,"severity":"error","filePath":"multi-stage-query/src/main/java/org/apache/druid/msq/indexing/IndexerTableInputSpecSlicer.java","lineNumber":235,"sourceCode":"    // If the task is operating with a REPLACE lock,\n    // any segment created after the lock was acquired for its interval will not be considered.\n    final Collection<DataSegment> publishedUsedSegments;\n    try {\n      // Additional check as the task action does not accept empty intervals\n      if (intervals.isEmpty()) {\n        publishedUsedSegments = Collections.emptySet();\n      } else {\n        publishedUsedSegments = taskActionClient.submit(\n            new RetrieveUsedSegmentsAction(\n                dataSource,\n                intervals,\n                SegmentDetail.none() // Even LoadSpec is not needed, because workers fetch them from the Coordinator.\n            )\n        );\n      }\n    }\n    catch (IOException e) {\n      throw new MSQException(e, UnknownFault.forException(e));\n    }\n\n    int realtimeCount = 0;\n\n    // Deduplicate segments, giving preference to published used segments.\n    // We do this so that if any segments have been handed off in between the two metadata calls above,\n    // we directly fetch it from deep storage.\n    Set<DataSegment> unifiedSegmentView = new HashSet<>(publishedUsedSegments);\n\n    // Iterate over the realtime segments and segments loaded on the historical\n    for (ImmutableSegmentLoadInfo segmentLoadInfo : realtimeAndHistoricalSegments) {\n      Set<DruidServerMetadata> servers = segmentLoadInfo.getServers();\n      // Filter out only realtime servers. We don't want to query historicals for now, but we can in the future.\n      // This check can be modified then.\n      Set<DruidServerMetadata> realtimeServerMetadata\n          = servers.stream()\n                   .filter(druidServerMetadata -> includeSegmentSource.getUsedServerTypes()\n                                                                      .contains(druidServerMetadata.getType())","sourceCodeStart":217,"sourceCodeEnd":253,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/multi-stage-query/src/main/java/org/apache/druid/msq/indexing/IndexerTableInputSpecSlicer.java#L217-L253","documentation":"IndexerTableInputSpecSlicer.getTimeline fetches the datasource timeline via coordinator/broker HTTP calls; an IOException during those calls is wrapped as MSQException(e, UnknownFault.forException(e)). It means the table input spec could not learn which segments back the datasource — a connectivity/IO failure against Coordinator or metadata, not a query-logic problem.","triggerScenarios":"Coordinator unreachable or returning connection reset during the timeline request; interrupted HTTP call (IOException) while reading segment metadata; TLS or DNS failures resolving the coordinator host.","commonSituations":"Coordinator restart or rolling upgrade while an MSQ query starts; network policy blocking peon→coordinator traffic; misconfigured druid.host / coordinator URL in the cluster config.","solutions":["Check coordinator availability and health endpoint; retry the query after the coordinator recovers","Verify network/DNS/TLS connectivity from the MSQ controller task to the coordinator","Inspect druid.coordination.coordinator config for wrong host/port","If recurring during upgrades, stagger coordinator restarts away from query launches"],"exampleFix":"// handling at call site\ntry {\n  timeline = slicer.timeline(spec);\n} catch (MSQException e) {\n  if (e.getCause() instanceof IOException) {\n    log.warn(\"Coordinator unreachable, retrying: %s\", e.getCause().getMessage());\n    // retry with backoff\n  } else { throw e; }\n}","handlingStrategy":"retry","validationCode":"// check coordinator health before submitting table-input MSQ queries\nHttpResponse r = get(coordinatorUrl + \"/status/health\");\nif (r.statusCode() != 200) throw new IllegalStateException(\"Coordinator unhealthy\");","typeGuard":null,"tryCatchPattern":"try {\n  timeline = slicer.timeline(spec);\n} catch (MSQException e) {\n  if (e.getCause() instanceof IOException) {\n    retryWithBackoff(); // coordinator may be restarting\n  } else { throw e; }\n}","preventionTips":["Avoid launching MSQ queries during coordinator restarts","Verify peon→coordinator network and DNS connectivity","Monitor coordinator availability metrics"],"tags":["msq","coordinator","io-exception","timeline"],"backgroundTag":"http-request-failed","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"}