{"record":{"id":"2ed6d6314632c2cf","repo":"apache/dolphinscheduler","slug":"fail-to-create-job","errorCode":null,"errorMessage":"fail to create job","messagePattern":"fail to create job","errorType":"exception","errorClass":"TaskException","httpStatus":null,"severity":"error","filePath":"dolphinscheduler-task-plugin/dolphinscheduler-task-api/src/main/java/org/apache/dolphinscheduler/plugin/task/api/utils/K8sUtils.java","lineNumber":48,"sourceCode":"import io.fabric8.kubernetes.client.KubernetesClient;\nimport io.fabric8.kubernetes.client.KubernetesClientBuilder;\nimport io.fabric8.kubernetes.client.Watch;\nimport io.fabric8.kubernetes.client.Watcher;\n\n@Slf4j\npublic class K8sUtils {\n\n    private KubernetesClient client;\n\n    public void createJob(String namespace, Job job) {\n        try {\n            client.batch()\n                    .v1()\n                    .jobs()\n                    .inNamespace(namespace)\n                    .create(job);\n        } catch (Exception e) {\n            throw new TaskException(\"fail to create job\", e);\n        }\n    }\n\n    public void deleteJob(String jobName, String namespace) {\n        try {\n            client.batch()\n                    .v1()\n                    .jobs()\n                    .inNamespace(namespace)\n                    .withName(jobName)\n                    .delete();\n        } catch (Exception e) {\n            throw new TaskException(\"fail to delete job\", e);\n        }\n    }\n\n    public Boolean jobExist(String jobName, String namespace) {\n        try {","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/apache/dolphinscheduler/blob/02eac45a1b6676e639fcbfb4be2243de5771b05d/dolphinscheduler-task-plugin/dolphinscheduler-task-api/src/main/java/org/apache/dolphinscheduler/plugin/task/api/utils/K8sUtils.java#L30-L66","documentation":"K8sUtils.createJob() submits a Batch/V1 Job to Kubernetes via the Fabric8 client and wraps any exception in a TaskException with message 'fail to create job'. It is a generic wrapper: the root cause (network, RBAC, validation) is attached as the cause and must be inspected.","triggerScenarios":"Calling createJob(jobName, namespace, ...) when the Kubernetes API server is unreachable, the kubeconfig is invalid, the namespace does not exist, RBAC denies Job creation, or the Job spec fails server-side validation.","commonSituations":"Worker cannot reach the K8s API server (network/DNS); kubeconfig YAML pasted incorrectly; target namespace deleted or misspelled; service account lacks the 'jobs create' permission; invalid job spec (bad image name, resource limits).","solutions":["Inspect the chained cause (e.getCause()) in worker logs to see the real Kubernetes client error.","Verify cluster connectivity from the worker: kubectl version / get ns using the same kubeconfig.","Confirm the namespace exists: kubectl get ns <namespace>, and create it if missing.","Check RBAC: bind the service account to a role allowing create on batch/jobs.","Validate the Job spec fields (image, resources) rendered by the task."],"exampleFix":"// before\n// assuming namespace exists\nk8sUtils.createJob(jobName, namespace, jobSpec);\n// after\nif (k8sUtils.namespaceExists(namespace)) {\n    k8sUtils.createJob(jobName, namespace, jobSpec);\n} else {\n    throw new IllegalStateException(\"namespace missing: \" + namespace);\n}","handlingStrategy":"try-catch","validationCode":"if (!k8sClientReachable() || !namespaceExists(namespace)) {\n    throw new IllegalStateException(\"K8s precheck failed before creating job \" + jobName);\n}","typeGuard":"boolean canCreateJobs(KubernetesClient client, String ns) {\n    return client.namespaces().withName(ns).get() != null;\n}","tryCatchPattern":"try {\n    k8sUtils.createJob(jobName, namespace, job);\n} catch (TaskException e) {\n    log.error(\"create job failed: {}\", e.getCause() == null ? e : e.getCause().getMessage(), e);\n    throw e;\n}","preventionTips":["Pre-check namespace existence and RBAC (can-i create jobs) with the same kubeconfig.","Validate rendered Job specs against the cluster version before submission.","Always log the chained cause of TaskException from K8sUtils for triage."],"tags":["kubernetes","job-creation","task-exception"],"backgroundTag":"http-error-response","analyzedSha":"02eac45a1b6676e639fcbfb4be2243de5771b05d","analyzedAt":"2026-09-06T17:43:00.555Z","contentChangedAt":"2026-09-06T17:43:00.555Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}