{"record":{"id":"7100ebcb03bd6415","repo":"apache/druid","slug":"failed-to-create-k8s-apiclient-instance","errorCode":null,"errorMessage":"Failed to create K8s ApiClient instance","messagePattern":"Failed to create K8s ApiClient instance","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"extensions-core/kubernetes-extensions/src/main/java/org/apache/druid/k8s/discovery/K8sDiscoveryModule.java","lineNumber":65,"sourceCode":"  {\n    return Collections.emptyList();\n  }\n\n  @Override\n  public void configure(Binder binder)\n  {\n    JsonConfigProvider.bind(binder, \"druid.discovery.k8s\", K8sDiscoveryConfig.class);\n\n    binder.bind(ApiClient.class)\n          .toProvider(\n              () -> {\n                try {\n                  // Note: we can probably improve things here about figuring out how to find the K8S API server,\n                  // HTTP client timeouts etc.\n                  return Config.defaultClient();\n                }\n                catch (IOException ex) {\n                  throw new RuntimeException(\"Failed to create K8s ApiClient instance\", ex);\n                }\n              }\n          )\n          .in(LazySingleton.class);\n\n    binder.bind(K8sApiClient.class).to(DefaultK8sApiClient.class).in(LazySingleton.class);\n    binder.bind(K8sLeaderElectorFactory.class).to(DefaultK8sLeaderElectorFactory.class).in(LazySingleton.class);\n\n    PolyBind.optionBinder(binder, Key.get(DruidNodeDiscoveryProvider.class))\n            .addBinding(K8S_KEY)\n            .to(K8sDruidNodeDiscoveryProvider.class)\n            .in(LazySingleton.class);\n\n    PolyBind.optionBinder(binder, Key.get(DruidNodeAnnouncer.class))\n            .addBinding(K8S_KEY)\n            .to(K8sDruidNodeAnnouncer.class)\n            .in(LazySingleton.class);\n","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/extensions-core/kubernetes-extensions/src/main/java/org/apache/druid/k8s/discovery/K8sDiscoveryModule.java#L47-L83","documentation":"A plain RuntimeException thrown from the Guice module's provider when io.kubernetes.client.openapi.Config.defaultClient() cannot build the default ApiClient — i.e. the in-cluster or kubeconfig configuration could not be loaded/initialized (IOException). This happens at first injection of the ApiClient (lazy singleton), typically at Druid startup with k8s discovery enabled.","triggerScenarios":"Config.defaultClient() throws IOException because the pod is not running inside Kubernetes (no KUBERNETES_SERVICE_HOST/PORT, missing /var/run/secrets/kubernetes.io/serviceaccount token) or the kubeconfig file is unreadable/invalid.","commonSituations":"Running Druid locally/in Docker outside a cluster with k8s discovery enabled; missing service-account token mount; RBAC-independent config loading failure; mispointed KUBECONFIG.","solutions":["Run the Druid process inside the Kubernetes cluster, or set KUBERNETES_SERVICE_HOST/PORT and provide a valid service-account token.","If using a kubeconfig, ensure the KUBECONFIG path is correct and the file is readable.","Check /var/run/secrets/kubernetes.io/serviceaccount/ exists and contains token/ca.crt.","Disable k8s discovery/announcer config if not deploying on Kubernetes."],"exampleFix":"// before: running locally with druid_discovery_k8s=true and no cluster access\n// after\nexport KUBERNETES_SERVICE_HOST=127.0.0.1\nexport KUBERNETES_SERVICE_PORT=6443\nexport KUBECONFIG=$HOME/.kube/config  # or run in-cluster with mounted SA token","handlingStrategy":"validation","validationCode":"// enable k8s discovery only when in-cluster or kubeconfig present\nboolean inCluster = System.getenv(\"KUBERNETES_SERVICE_HOST\") != null && System.getenv(\"KUBERNETES_SERVICE_PORT\") != null;\nboolean hasKubeconfig = System.getenv(\"KUBECONFIG\") != null || new File(System.getProperty(\"user.home\", \"/root\") + \"/.kube/config\").exists();\nboolean hasSaToken = new File(\"/var/run/secrets/kubernetes.io/serviceaccount/token\").exists();\nif (!(inCluster && hasSaToken) && !hasKubeconfig) throw new IllegalStateException(\"K8s client config unavailable; disable k8s discovery or fix credentials\");","typeGuard":null,"tryCatchPattern":"try {\n  ApiClient client = injector.getInstance(ApiClient.class);\n} catch (CreationException e) {\n  LOG.error(e, \"K8s ApiClient init failed; check KUBERNETES_SERVICE_HOST and SA token\");\n  throw e;\n}","preventionTips":["Only enable druid k8s discovery/announcer when deploying inside Kubernetes.","Ensure the service-account token and ca.crt are mounted at /var/run/secrets/kubernetes.io/serviceaccount.","Set KUBECONFIG explicitly for out-of-cluster development.","Fail fast at startup with a config check instead of a lazy-init surprise."],"tags":["kubernetes","guice","client-init","configuration"],"backgroundTag":"module-init-failed","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}