hashicorp/nomad · error
gcs_timeout must be > 0
Error message
gcs_timeout must be > 0
What it means
Returned by ArtifactConfig.Validate when gcs_timeout parses as a duration but is negative. Nomad requires a non-negative timeout; a negative value is nonsensical (the download would be considered already expired) so the config is rejected. Note zero passes this check even though the message says "> 0".
Source
Thrown at nomad/structs/config/artifact.go:190
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")
}
if a.GitTimeout == nil {
return fmt.Errorf("git_timeout must be set")
}
if v, err := time.ParseDuration(*a.GitTimeout); err != nil {
return fmt.Errorf("git_timeout not a valid duration: %w", err)
} else if v < 0 {
return fmt.Errorf("git_timeout must be > 0")
}
if a.HgTimeout == nil {
return fmt.Errorf("hg_timeout must be set")
}
if v, err := time.ParseDuration(*a.HgTimeout); err != nil {
return fmt.Errorf("hg_timeout not a valid duration: %w", err)
} else if v < 0 {
return fmt.Errorf("hg_timeout must be > 0")View on GitHub (pinned to 482b49bf1a)
Solutions
- Change gcs_timeout to a positive duration such as "5m".
- If you want no timeout, use a very large positive duration rather than a negative or zero sentinel.
- Fix any computation/templating that emits negative numbers and clamp to a minimum value.
Example fix
// before
artifact {
gcs_timeout = "-5m"
}
// after
artifact {
gcs_timeout = "5m"
} Defensive patterns
Strategy: validation
Validate before calling
func nonNegativeDuration(s string) bool {
v, err := time.ParseDuration(s)
return err == nil && v >= 0
} Type guard
func isPositiveDuration(s string) bool {
v, err := time.ParseDuration(s)
return err == nil && v >= 0
} Prevention
- Clamp computed timeouts to >= 0 before writing config.
- Never use negative values as 'unlimited' sentinels.
- Check for stray minus signs when hand-editing HCL.
When it happens
Trigger: Setting `gcs_timeout = "-5m"` or "-1s"; arithmetic or templating producing a negative number (e.g. subtracting durations, negative env var); sign typos in HCL config.
Common situations: Dynamically computing a timeout that went negative due to clock/ordering mistakes; accidentally prefixing a minus sign; misunderstanding that 0 is allowed and trying "-1" as a sentinel.
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
- gcs_timeout not a valid duration: %w
- git_timeout not a valid duration: %w
- git_timeout must be > 0
- hg_timeout not a valid duration: %w
- wait config is nil or empty
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/cda555d333cefbed.
Report an issue: GitHub.