{"record":{"id":"4df03fe84c6ef2f4","repo":"hashicorp/nomad","slug":"missing-job-region","errorCode":null,"errorMessage":"Missing job region","messagePattern":"Missing job region","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/structs/structs.go","lineNumber":4741,"sourceCode":"\t\ttgs := make([]*TaskGroup, len(j.TaskGroups))\n\t\tfor i, tg := range j.TaskGroups {\n\t\t\ttgs[i] = tg.Copy()\n\t\t}\n\t\tnj.TaskGroups = tgs\n\t}\n\n\tnj.Periodic = j.Periodic.Copy()\n\tnj.Meta = maps.Clone(j.Meta)\n\tnj.ParameterizedJob = j.ParameterizedJob.Copy()\n\treturn nj\n}\n\n// Validate is used to check a job for reasonable configuration\nfunc (j *Job) Validate() error {\n\tvar mErr multierror.Error\n\n\tif j.Region == \"\" && j.Multiregion == nil {\n\t\tmErr.Errors = append(mErr.Errors, errors.New(\"Missing job region\"))\n\t}\n\tif j.ID == \"\" {\n\t\tmErr.Errors = append(mErr.Errors, errors.New(\"Missing job ID\"))\n\t} else if strings.Contains(j.ID, \" \") {\n\t\tmErr.Errors = append(mErr.Errors, errors.New(\"Job ID contains a space\"))\n\t} else if strings.Contains(j.ID, \"\\000\") {\n\t\tmErr.Errors = append(mErr.Errors, errors.New(\"Job ID contains a null character\"))\n\t}\n\tif j.Name == \"\" {\n\t\tmErr.Errors = append(mErr.Errors, errors.New(\"Missing job name\"))\n\t} else if strings.Contains(j.Name, \"\\000\") {\n\t\tmErr.Errors = append(mErr.Errors, errors.New(\"Job Name contains a null character\"))\n\t}\n\n\tif j.Namespace == \"\" {\n\t\tmErr.Errors = append(mErr.Errors, errors.New(\"Job must be in a namespace\"))\n\t}\n\tswitch j.Type {","sourceCodeStart":4723,"sourceCodeEnd":4759,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/structs/structs.go#L4723-L4759","documentation":"Job.Validate requires the job to declare a region unless it is a multiregion job, in which case regions come from the multiregion block. An empty j.Region with j.Multiregion == nil fails with \"Missing job region\".","triggerScenarios":"Submitting a job spec whose region field is empty/omitted and which has no multiregion stanza; constructing a Job struct in Go with Region unset and calling Validate.","commonSituations":"Hand-written HCL/JSON jobs missing region = \"global\" (the default most clusters use); API-driven job submission where the region field was dropped during serialization; template rendering producing empty region.","solutions":["Add region = \"global\" (or your target region) to the job block","If the job should run in many regions, add a multiregion { region { ... } } stanza instead","Check CLI flags / templates so region isn't rendered empty on submission"],"exampleFix":"// before\njob \"example\" {\n  datacenters = [\"dc1\"]\n}\n// after\njob \"example\" {\n  region      = \"global\"\n  datacenters = [\"dc1\"]\n}","handlingStrategy":"validation","validationCode":"function validateJobRegion(job) {\n  if (!job.region && !job.multiregion) {\n    throw new Error(\"job must set region (e.g. 'global') or a multiregion block\");\n  }\n}","typeGuard":"function hasRegion(j) { return typeof j.region === \"string\" && j.region.length > 0 || j.multiregion != null; }","tryCatchPattern":"try {\n  await nomad.jobs.validate(job);\n} catch (e) {\n  if (e.message === \"Missing job region\") {\n    console.error(\"Add region = \\\"global\\\" or a multiregion block to the job\");\n  } else throw e;\n}","preventionTips":["Always include region = \"global\" in job templates unless multiregion is used","Check that API payloads preserve the region field after serialization","Run nomad job validate in CI for every job spec"],"tags":["nomad","region","job-validation","job-spec"],"backgroundTag":"missing-required-argument","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}