hashicorp/nomad · error

lost_after cannot be a negative duration

Error message

lost_after cannot be a negative duration

What it means

errNegativeLostAfter is a disconnect-strategy validation error: lost_after must be zero or a positive duration. A negative value makes no temporal sense (it would mark the client lost before it disconnects), so Validate rejects the job.

Source

Thrown at nomad/structs/group.go:27

	"time"

	"github.com/hashicorp/go-multierror"
)

const (
	// ReconcileOption is used to specify the behavior of the reconciliation process
	// between the original allocations and the replacements when a previously
	// disconnected client comes back online.
	ReconcileOptionKeepOriginal    = "keep_original"
	ReconcileOptionKeepReplacement = "keep_replacement"
	ReconcileOptionBestScore       = "best_score"
	ReconcileOptionLongestRunning  = "longest_running"
)

var (
	// Disconnect strategy validation errors
	errStopAndLost         = errors.New("Disconnect cannot be configured with both lost_after and stop_after")
	errNegativeLostAfter   = errors.New("lost_after cannot be a negative duration")
	errNegativeStopAfter   = errors.New("stop_after cannot be a negative duration")
	errStopAfterNonService = errors.New("stop_after can only be used with service or batch job types")
	errInvalidReconcile    = errors.New("reconcile option is invalid")
)

func NewDefaultDisconnectStrategy() *DisconnectStrategy {
	return &DisconnectStrategy{
		Replace:   new(true),
		Reconcile: ReconcileOptionBestScore,
	}
}

// Disconnect strategy defines how both clients and server should behave in case of
// disconnection between them.
type DisconnectStrategy struct {
	// Defines for how long the server will consider the unresponsive node as
	// disconnected but alive instead of lost.
	LostAfter time.Duration `mapstructure:"lost_after" hcl:"lost_after,optional"`

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Set lost_after to a positive duration (e.g. "2h") or remove it to use the default
  2. Clamp computed/templated durations to >= 0 before rendering the job file
  3. Run 'nomad job validate' to catch the negative value before submission

Example fix

// before
disconnect {
  lost_after = "-5m"
}
// after
disconnect {
  lost_after = "5m"
}
Defensive patterns

Strategy: validation

Validate before calling

if ds := grp.Disconnect; ds != nil && ds.LostAfter < 0 {
    return fmt.Errorf("disconnect: lost_after must be >= 0, got %s", ds.LostAfter)
}

Type guard

func lostAfterValid(ds *api.DisconnectStrategy) bool {
    return ds == nil || ds.LostAfter >= 0
}

Try / catch

err := client.Jobs().Validate(job, nil, nil)
if err != nil && strings.Contains(err.Error(), "lost_after cannot be a negative duration") {
    return fmt.Errorf("fix lost_after to a positive duration: %w", err)
}

Prevention

When it happens

Trigger: Submitting a job whose group disconnect block has lost_after set to a negative duration, checked at group.go:84 in DisconnectStrategy.Validate.

Common situations: HCL negative durations like lost_after = "-5m" from templating bugs or manual typos; variables interpolated from data that can go negative (e.g. difference of timestamps); copy-paste errors.

Related errors


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