hashicorp/nomad · error
Missing Log Config
Error message
Missing Log Config
What it means
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.
Source
Thrown at nomad/structs/structs.go:8279
if conflictsWithProgressDeadline {
mErr.Errors = append(mErr.Errors, fmt.Errorf("KillTimout (%s) longer than the group's ProgressDeadline (%s)",
t.KillTimeout, tg.Update.ProgressDeadline))
}
}
if t.ShutdownDelay < 0 {
mErr.Errors = append(mErr.Errors, errors.New("ShutdownDelay must be a positive value"))
}
// Validate the resources.
if t.Resources == nil {
mErr.Errors = append(mErr.Errors, errors.New("Missing task resources"))
} else if err := t.Resources.Validate(); err != nil {
mErr.Errors = append(mErr.Errors, err)
}
// Validate the log config
if t.LogConfig == nil {
mErr.Errors = append(mErr.Errors, errors.New("Missing Log Config"))
} else if err := t.LogConfig.Validate(tg.EphemeralDisk); err != nil {
mErr.Errors = append(mErr.Errors, err)
}
// Validate constraints and affinities.
for idx, constr := range t.Constraints {
if err := constr.Validate(); err != nil {
outer := fmt.Errorf("Constraint %d validation failed: %s", idx+1, err)
mErr.Errors = append(mErr.Errors, outer)
}
switch constr.Operand {
case ConstraintDistinctHosts, ConstraintDistinctProperty:
outer := fmt.Errorf("Constraint %d has disallowed Operand at task level: %s", idx+1, constr.Operand)
mErr.Errors = append(mErr.Errors, outer)
}
}
View on GitHub (pinned to 482b49bf1a)
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.
Example fix
// before (Go)
task := &structs.Task{Name: "app", Driver: "docker"}
// after
task := &structs.Task{Name: "app", Driver: "docker"}
task.LogConfig = &structs.LogConfig{MaxFiles: 2, MaxFileSizeMB: 10} Defensive patterns
Strategy: validation
Validate before calling
func validateTaskLogConfig(t *structs.Task) error {
if t.LogConfig == nil {
return fmt.Errorf("task %q: LogConfig is required", t.Name)
}
return nil
} Type guard
func hasLogConfig(t *structs.Task) bool { return t != nil && t.LogConfig != nil } Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- minimum number of files is 1; got %d
- minimum file size is 1MB; got %d
- Disconnect cannot be configured with both lost_after and sto
- lost_after cannot be a negative duration
- stop_after cannot be a negative duration
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/3e7336f044151e85.
Report an issue: GitHub.