{"record":{"id":"d3c6e024a7967034","repo":"hashicorp/nomad","slug":"error-in-job-mutator-s-v","errorCode":null,"errorMessage":"error in job mutator %s: %v","messagePattern":"error in job mutator (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/job_endpoint_hooks.go","lineNumber":202,"sourceCode":"\t}\n\n\tvalidateWarnings, err := j.admissionValidators(job)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\twarnings = append(warnings, validateWarnings...)\n\n\treturn out, warnings, nil\n}\n\n// admissionMutator returns an updated job as well as warnings or an error.\nfunc (j *Job) admissionMutators(job *structs.Job) (_ *structs.Job, warnings []error, err error) {\n\tvar w []error\n\tfor _, mutator := range j.mutators {\n\t\tjob, w, err = mutator.Mutate(job)\n\t\tj.logger.Trace(\"job mutate results\", \"mutator\", mutator.Name(), \"warnings\", w, \"error\", err)\n\t\tif err != nil {\n\t\t\treturn nil, nil, fmt.Errorf(\"error in job mutator %s: %v\", mutator.Name(), err)\n\t\t}\n\t\twarnings = append(warnings, w...)\n\t}\n\treturn job, warnings, err\n}\n\n// admissionValidators returns a slice of validation warnings and a multierror\n// of validation failures.\nfunc (j *Job) admissionValidators(origJob *structs.Job) ([]error, error) {\n\t// ensure job is not mutated\n\tjob := origJob.Copy()\n\n\tvar warnings []error\n\tvar errs error\n\n\tfor _, validator := range j.validators {\n\t\tw, err := validator.Validate(job)\n\t\tj.logger.Trace(\"job validate results\", \"validator\", validator.Name(), \"warnings\", w, \"error\", err)","sourceCodeStart":184,"sourceCodeEnd":220,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/job_endpoint_hooks.go#L184-L220","documentation":"Nomad runs job mutator hooks during job admission (Validate/registration). If any mutator's Mutate returns a non-nil error, admission aborts and this wrapped error, embedding the mutator's name and the underlying error, is returned to the caller.","triggerScenarios":"Calling the Validate or job register API on a job where a registered mutator hook (e.g. the connect/interpolation mutator) fails while transforming the job.","commonSituations":"Malformed Consul Connect configuration that the connect interpolation mutator cannot process; custom/enterprise mutators choking on unsupported job fields; internal mutator bugs after version upgrades.","solutions":["Read the embedded mutator name (%s) and inner error to find which hook failed and why","Fix the job field the named mutator rejects (typically the connect/sidecar or interpolation block)","Upgrade Nomad if the failure is a known mutator bug","Temporarily remove the offending job stanza to confirm which hook errors"],"exampleFix":"// before\nservice { connect { sidecar_service { proxy { upstreams { destination_name = \"\" } } } } }\n// after\nservice { connect { sidecar_service { proxy { upstreams { destination_name = \"count-api\" } } } } }","handlingStrategy":"try-catch","validationCode":"// run first: nomad job validate job.nomad.hcl (or POST /v1/validate) before register","typeGuard":null,"tryCatchPattern":"if err := client.Jobs().Register(job, nil, nil); err != nil {\n\tvar me *multierror.Error\n\tif errors.As(err, &me) {\n\t\tfor _, e := range me.Errors { log.Printf(\"mutator failure: %v\", e) }\n\t}\n\treturn fmt.Errorf(\"job admission failed: %w\", err)\n}","preventionTips":["Always call the Validate API before register in CI","Keep connect/sidecar stanzas minimal and complete","Pin Nomad versions and read changelogs for hook changes"],"tags":["nomad","job-mutation","admission-hook","validation"],"backgroundTag":"job-mutator-failed","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"}