hashicorp/nomad · error
http_read_timeout must be > 0
Error message
http_read_timeout must be > 0
What it means
Once http_read_timeout parses as a duration, Validate rejects negative values with this message. A negative HTTP read timeout is meaningless for artifact fetching, so the config is treated as invalid. Note the message text says '> 0' while the code checks v < 0; only strictly negative durations trigger it.
Source
Thrown at nomad/structs/config/artifact.go:172
return false
case !pointer.Eq(a.SetEnvironmentVariables, o.SetEnvironmentVariables):
return false
}
return true
}
func (a *ArtifactConfig) Validate() error {
if a == nil {
return fmt.Errorf("artifact must not be nil")
}
if a.HTTPReadTimeout == nil {
return fmt.Errorf("http_read_timeout must be set")
}
if v, err := time.ParseDuration(*a.HTTPReadTimeout); err != nil {
return fmt.Errorf("http_read_timeout not a valid duration: %w", err)
} else if v < 0 {
return fmt.Errorf("http_read_timeout must be > 0")
}
if a.HTTPMaxSize == nil {
return fmt.Errorf("http_max_size must be set")
}
if v, err := humanize.ParseBytes(*a.HTTPMaxSize); err != nil {
return fmt.Errorf("http_max_size not a valid size: %w", err)
} else if v > math.MaxInt64 {
return fmt.Errorf("http_max_size must be < %d but found %d", int64(math.MaxInt64), v)
}
if a.GCSTimeout == nil {
return fmt.Errorf("gcs_timeout must be set")
}
if v, err := time.ParseDuration(*a.GCSTimeout); err != nil {
return fmt.Errorf("gcs_timeout not a valid duration: %w", err)
} else if v < 0 {
return fmt.Errorf("gcs_timeout must be > 0")View on GitHub (pinned to 482b49bf1a)
Solutions
- Set a positive duration, e.g. http_read_timeout = "30s".
- If a timeout-free behavior is desired, check Nomad docs for the supported 'no timeout' representation instead of using a negative value.
- Add a config lint/CI check that artifact durations are > 0.
- Fix any code generating durations via time arithmetic that may go negative.
Example fix
// before
artifact {
http_read_timeout = "-30s"
}
// after
artifact {
http_read_timeout = "30s"
} Defensive patterns
Strategy: validation
Validate before calling
if v, err := time.ParseDuration(cfg.Artifact.HTTPReadTimeout); err == nil && v < 0 {
return fmt.Errorf("http_read_timeout must be positive")
} Try / catch
if err := cfg.Artifact.Validate(); err != nil {
if strings.Contains(err.Error(), "must be > 0") {
// replace the negative duration with a positive one
}
return err
} Prevention
- Never configure negative durations; use positive values only.
- Check template interpolation for expressions that can yield negatives.
- Add config assertions that all duration options are > 0.
When it happens
Trigger: Configuring artifact { http_read_timeout = "-30s" } or computing a duration programmatically that came out negative (e.g. subtracting timestamps when generating config).
Common situations: Hand-edited configs after failed experiments; templating systems that interpolate negative values; accidentally using a negative sentinel to mean 'unlimited'.
Understand the failure class
Background: "invalid duration" / "failed to parse duration": why your timeout, interval, or TTL string is rejected and which formats each library accepts — this error's family across 32 libraries.
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- http_read_timeout not a valid duration: %w
- wait config is nil or empty
- missing datacenter for client registration
- default_identity_ttl must be greater than 0
- max_identity_ttl must be greater than 0
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/e20f7fd059db54db.
Report an issue: GitHub.