{"record":{"id":"cc3f38b2de31bc4c","repo":"apache/druid","slug":"grpc-query-server-shutdown-failed","errorCode":null,"errorMessage":"gRPC query server shutdown failed","messagePattern":"gRPC query server shutdown failed","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"extensions-contrib/grpc-query/src/main/java/org/apache/druid/grpc/server/GrpcEndpointInitializer.java","lineNumber":120,"sourceCode":"      // (that is, class loader issues in an IDE, or a jar missing in the extension).\n      log.error(t, \"Fatal error: gRPC query server startup failed\");\n\n      // This exception will bring down the Broker as there is not much we can\n      // do if we can't start the gRPC endpoint.\n      throw t;\n    }\n  }\n\n  @LifecycleStop\n  public void stop()\n  {\n    if (server != null) {\n      try {\n        server.blockUntilShutdown();\n      }\n      catch (InterruptedException e) {\n        // Just warn. We're shutting down anyway, so no need to throw an exception.\n        log.warn(e, \"gRPC query server shutdown failed\");\n      }\n      server = null;\n    }\n  }\n}\n","sourceCodeStart":102,"sourceCodeEnd":126,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/extensions-contrib/grpc-query/src/main/java/org/apache/druid/grpc/server/GrpcEndpointInitializer.java#L102-L126","documentation":"When the gRPC query server extension stops, GrpcEndpointInitializer.stop blocks until the gRPC server terminates. If that wait is interrupted (thread interrupt during Druid shutdown), the InterruptedException is caught and logged as this warning rather than propagated, because the process is shutting down anyway.","triggerScenarios":"Calling stop() while server.blockUntilShutdown() is waiting, and the calling thread is interrupted — e.g., lifecycle stop during process shutdown, Jetty lifecycle shutdown, or a shutdown hook interrupting worker threads.","commonSituations":"Normal Druid process termination or SIGTERM handling where lifecycle stop order interrupts the gRPC wait; tests that interrupt threads during teardown.","solutions":["Generally benign during shutdown — no action needed if it appears only at process exit.","If seen outside shutdown, find what is interrupting the lifecycle thread (thread dumps, interrupt() callers) and fix the premature interrupt.","Ensure server.shutdown() is called before waiting so blockUntilShutdown completes promptly; restore the interrupt status if you change the code (Thread.currentThread().interrupt())."],"exampleFix":"// before\ncatch (InterruptedException e) {\n  log.warn(e, \"gRPC query server shutdown failed\");\n}\n// after\ncatch (InterruptedException e) {\n  Thread.currentThread().interrupt();\n  log.warn(e, \"gRPC query server shutdown interrupted; continuing shutdown\");\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"if (server != null) { server.shutdown(); } // null-guard before blocking on shutdown","tryCatchPattern":"try {\n  server.blockUntilShutdown();\n} catch (InterruptedException e) {\n  Thread.currentThread().interrupt(); // preserve interrupt status\n  log.warn(e, \"gRPC server shutdown interrupted\");\n}","preventionTips":["Call server.shutdown() (graceful) before blockUntilShutdown() so the wait is short.","Treat this as benign during SIGTERM; only investigate if it appears during normal operation.","Preserve interrupt status in any custom lifecycle code to keep Druid shutdown orderly.","Keep lifecycle stop hooks non-blocking where possible."],"tags":["grpc","shutdown","interrupted","lifecycle"],"backgroundTag":"request-timeout","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"}