hashicorp/nomad · error

Lifecycle validation failed: %v

Error message

Lifecycle validation failed: %v

What it means

Task.Validate wraps Lifecycle.Validate failures as "Lifecycle validation failed: %v". Lifecycle blocks mark tasks as prestart/poststart/sidecar hooks, and validation rejects invalid hook names or illegal lifecycle configurations (e.g. on a system job).

Source

Thrown at nomad/structs/structs.go:8373

		if handled, seen := actions[action.Name]; seen && !handled {
			mErr.Errors = append(mErr.Errors, fmt.Errorf("Action %s defined multiple times", action.Name))
			actions[action.Name] = true
			continue
		}
		actions[action.Name] = false
	}

	// Validate the dispatch payload block if there
	if t.DispatchPayload != nil {
		if err := t.DispatchPayload.Validate(); err != nil {
			mErr.Errors = append(mErr.Errors, fmt.Errorf("Dispatch Payload validation failed: %v", err))
		}
	}

	// Validate the Lifecycle block if there
	if t.Lifecycle != nil {
		if err := t.Lifecycle.Validate(); err != nil {
			mErr.Errors = append(mErr.Errors, fmt.Errorf("Lifecycle validation failed: %v", err))
		}

	}

	// Validation for TaskKind field which is used for Consul Connect integration
	if t.Kind.IsConnectProxy() {
		// This task is a Connect proxy so it should not have service blocks
		if len(t.Services) > 0 {
			mErr.Errors = append(mErr.Errors, fmt.Errorf("Connect proxy task must not have a service block"))
		}
		if t.Leader {
			mErr.Errors = append(mErr.Errors, fmt.Errorf("Connect proxy task must not have leader set"))
		}

		// Ensure the proxy task has a corresponding service entry
		serviceErr := ValidateConnectProxyService(t.Kind.Value(), tg.Services)
		if serviceErr != nil {
			mErr.Errors = append(mErr.Errors, serviceErr)

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Read the wrapped inner error to see which lifecycle field is invalid
  2. Use only supported hook values: PRESTART, POSTSTART, POSTSTOP
  3. Remove lifecycle from tasks where it is unsupported (e.g. system scheduler jobs)

Example fix

// before
lifecycle {
  hook = "prestart-after"
}
// after
lifecycle {
  hook = "prestart"
}
Defensive patterns

Strategy: validation

Validate before calling

if task.Lifecycle != nil {
    if err := task.Lifecycle.Validate(); err != nil {
        return fmt.Errorf("lifecycle: %w", err)
    }
}

Type guard

var validHooks = map[string]bool{"PRESTART": true, "POSTSTART": true, "POSTSTOP": true}
func hookValid(h string) bool { return validHooks[h] }

Try / catch

if err := job.Validate(); err != nil {
    if strings.Contains(err.Error(), "Lifecycle validation failed") { /* fix lifecycle block */ }
}

Prevention

When it happens

Trigger: A task's `lifecycle` block specifies an invalid `hook` value or a `sidecar`/hook combination that fails validation, e.g. lifecycle on unsupported job types.

Common situations: Misspelling hook="PRESTART" casing; adding sidecar tasks to system jobs; upgrading jobs written for older Nomad lifecycle semantics.

Related errors


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/7c17394697310764. Report an issue: GitHub.