{"record":{"id":"212c74735decff9d","repo":"apache/druid","slug":"pod-adapter-s-requires-the-local-overlord-pod-n","errorCode":null,"errorMessage":"Pod adapter [%s] requires the local Overlord pod namespace for multik8s. Set either [druid.indexer.runner.overlordNamespace] or [druid.indexer.runner.namespace], or set [druid.indexer.runner.k8s.adapter.type=%s].","messagePattern":"Pod adapter \\[(.+?)\\] requires the local Overlord pod namespace for multik8s\\. Set either \\[druid\\.indexer\\.runner\\.overlordNamespace\\] or \\[druid\\.indexer\\.runner\\.namespace\\], or set \\[druid\\.indexer\\.runner\\.k8s\\.adapter\\.type=(.+?)\\]\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"extensions-core/kubernetes-overlord-extensions/src/main/java/org/apache/druid/k8s/overlord/MultipleKubernetesTaskRunnerFactory.java","lineNumber":433,"sourceCode":"  {\n    final String overlordNamespace = runnerConfig.getOverlordNamespace();\n    if (overlordNamespace != null && !overlordNamespace.trim().isEmpty()) {\n      return overlordNamespace;\n    }\n\n    final String namespace = runnerConfig.getNamespace();\n    if (namespace != null && !namespace.trim().isEmpty()) {\n      return namespace;\n    }\n\n    if (enabledClusters.size() == 1) {\n      final MultipleKubernetesTaskRunnerConfig.KubernetesCluster cluster = enabledClusters.get(0);\n      if (cluster.getKubeconfigPath() == null || cluster.getKubeconfigPath().trim().isEmpty()) {\n        return cluster.getTaskNamespace();\n      }\n    }\n\n    throw new IAE(\n        \"Pod adapter [%s] requires the local Overlord pod namespace for multik8s. Set either \"\n        + \"[druid.indexer.runner.overlordNamespace] or [druid.indexer.runner.namespace], or set \"\n        + \"[druid.indexer.runner.k8s.adapter.type=%s].\",\n        getAdapterType() == null ? SingleContainerTaskAdapter.TYPE : getAdapterType(),\n        PodTemplateTaskAdapter.TYPE\n    );\n  }\n\n  private KubernetesTaskRunnerStaticConfig getPerClusterConfiguration(\n      MultipleKubernetesTaskRunnerConfig.KubernetesCluster cluster\n  )\n  {\n    return new KubernetesTaskRunnerStaticConfig(\n        cluster.getTaskNamespace(),\n        cluster.getOverlordIdentifier(),\n        this.runnerConfig.getK8sTaskPodNamePrefix(),\n        this.runnerConfig.isDebugJobs(),\n        this.runnerConfig.isSidecarSupport(),","sourceCodeStart":415,"sourceCodeEnd":451,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/extensions-core/kubernetes-overlord-extensions/src/main/java/org/apache/druid/k8s/overlord/MultipleKubernetesTaskRunnerFactory.java#L415-L451","documentation":"Thrown by getOverlordPodSourceNamespace in MultipleKubernetesTaskRunnerFactory when a pod-template-based adapter (PodTemplateTaskAdapter) is selected but the Overlord's own pod namespace cannot be determined from the multik8s cluster configuration. The pod template runs tasks in the Overlord's namespace, so Druid requires either an explicit overlordNamespace/namespace property or a cluster entry without a kubeconfigPath (local cluster) that defines a taskNamespace.","triggerScenarios":"Configuring druid.indexer.runner.k8s.adapter.type=podTemplate (or the primary cluster uses a pod adapter) while: enabledClusters is empty, or the only enabled cluster has a non-empty kubeconfigPath (remote cluster, so its namespace is not the Overlord's local namespace) and neither druid.indexer.runner.overlordNamespace nor druid.indexer.runner.namespace is set.","commonSituations":"Multi-cluster (multik8s) setups where every cluster entry specifies a kubeconfigPath; fresh deployments that enabled the podTemplate adapter but never set the Overlord namespace property; operators assuming the cluster's taskNamespace doubles as the Overlord pod namespace.","solutions":["Set druid.indexer.runner.overlordNamespace (or druid.indexer.runner.namespace) to the namespace the Overlord pod runs in","If the Overlord runs inside one of the configured clusters, remove kubeconfigPath from that cluster entry so its taskNamespace is used","Alternatively switch to a different adapter via druid.indexer.runner.k8s.adapter.type=e.g. singleContainer or multiContainer, which does not require the local namespace"],"exampleFix":"// before\ndruid.indexer.runner.k8s.adapter.type=podTemplate\n# no namespace configured\n\n// after\ndruid.indexer.runner.k8s.adapter.type=podTemplate\ndruid.indexer.runner.overlordNamespace=druid","handlingStrategy":"validation","validationCode":"String adapter = props.getProperty(\"druid.indexer.runner.k8s.adapter.type\");\nString ns = props.getProperty(\"druid.indexer.runner.overlordNamespace\",\n            props.getProperty(\"druid.indexer.runner.namespace\"));\nif ((\"podTemplate\".equals(adapter) || adapter == null) && ns == null) {\n    throw new IllegalArgumentException(\n        \"podTemplate adapter needs druid.indexer.runner.overlordNamespace or druid.indexer.runner.namespace\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always set druid.indexer.runner.overlordNamespace explicitly in multi-cluster setups","Remember: clusters with a kubeconfigPath are remote and cannot supply the Overlord's local namespace","For remote-only clusters, prefer druid.indexer.runner.k8s.adapter.type=podTemplate only when a local namespace exists"],"tags":["kubernetes","configuration","namespace","druid-overlord"],"backgroundTag":"missing-required-config-field","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"}