{"record":{"id":"3e7336f044151e85","repo":"hashicorp/nomad","slug":"missing-log-config","errorCode":null,"errorMessage":"Missing Log Config","messagePattern":"Missing Log Config","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/structs/structs.go","lineNumber":8279,"sourceCode":"\t\tif conflictsWithProgressDeadline {\n\t\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"KillTimout (%s) longer than the group's ProgressDeadline (%s)\",\n\t\t\t\tt.KillTimeout, tg.Update.ProgressDeadline))\n\t\t}\n\t}\n\tif t.ShutdownDelay < 0 {\n\t\tmErr.Errors = append(mErr.Errors, errors.New(\"ShutdownDelay must be a positive value\"))\n\t}\n\n\t// Validate the resources.\n\tif t.Resources == nil {\n\t\tmErr.Errors = append(mErr.Errors, errors.New(\"Missing task resources\"))\n\t} else if err := t.Resources.Validate(); err != nil {\n\t\tmErr.Errors = append(mErr.Errors, err)\n\t}\n\n\t// Validate the log config\n\tif t.LogConfig == nil {\n\t\tmErr.Errors = append(mErr.Errors, errors.New(\"Missing Log Config\"))\n\t} else if err := t.LogConfig.Validate(tg.EphemeralDisk); err != nil {\n\t\tmErr.Errors = append(mErr.Errors, err)\n\t}\n\n\t// Validate constraints and affinities.\n\tfor idx, constr := range t.Constraints {\n\t\tif err := constr.Validate(); err != nil {\n\t\t\touter := fmt.Errorf(\"Constraint %d validation failed: %s\", idx+1, err)\n\t\t\tmErr.Errors = append(mErr.Errors, outer)\n\t\t}\n\n\t\tswitch constr.Operand {\n\t\tcase ConstraintDistinctHosts, ConstraintDistinctProperty:\n\t\t\touter := fmt.Errorf(\"Constraint %d has disallowed Operand at task level: %s\", idx+1, constr.Operand)\n\t\t\tmErr.Errors = append(mErr.Errors, outer)\n\t\t}\n\t}\n","sourceCodeStart":8261,"sourceCodeEnd":8297,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/structs/structs.go#L8261-L8297","documentation":"Task.Validate() requires a non-nil LogConfig. The log config controls rotation/size of stdout/stderr collection; when it is nil Nomad cannot compute the task's log storage footprint (validated against the group's EphemeralDisk), so it appends this error to the multierror and rejects the task.","triggerScenarios":"Registering a job where the task's LogConfig field is nil — either no logs block in HCL in contexts where defaults weren't applied, or building a Task in Go without setting LogConfig before Validate.","commonSituations":"Programmatic job generation that omits LogConfig (job submission via raw API/JSON where the agent's defaulting hook didn't run); writing validation tests that construct bare Task structs; versions where client-side defaulting differs from server-side validation.","solutions":["Add a logs block to the task (e.g. max_files = 2, max_file_size = 10) or submit through the normal job endpoint so Nomad defaults apply.","If constructing in Go, set t.LogConfig = &nomadstructs.LogConfig{MaxFiles: 2, MaxFileSizeMB: 10} before Validate.","Check that you're not bypassing the canonical job canonicalization step (Jobs.Structs -> Canonicalize) which normally injects defaults.","Use `nomad job validate` locally to catch it before submission."],"exampleFix":"// before (Go)\ntask := &structs.Task{Name: \"app\", Driver: \"docker\"}\n// after\ntask := &structs.Task{Name: \"app\", Driver: \"docker\"}\ntask.LogConfig = &structs.LogConfig{MaxFiles: 2, MaxFileSizeMB: 10}","handlingStrategy":"validation","validationCode":"func validateTaskLogConfig(t *structs.Task) error {\n\tif t.LogConfig == nil {\n\t\treturn fmt.Errorf(\"task %q: LogConfig is required\", t.Name)\n\t}\n\treturn nil\n}","typeGuard":"func hasLogConfig(t *structs.Task) bool { return t != nil && t.LogConfig != nil }","tryCatchPattern":null,"preventionTips":["Submit jobs through the canonical job endpoint so Nomad applies default log config.","When constructing Task structs directly, always set LogConfig (e.g. MaxFiles: 2, MaxFileSizeMB: 10).","Add a lint rule in job templates that flags task blocks without a logs stanza."],"tags":["nomad","job-spec","validation","logging"],"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"}