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

  1. Set a positive duration, e.g. http_read_timeout = "30s".
  2. If a timeout-free behavior is desired, check Nomad docs for the supported 'no timeout' representation instead of using a negative value.
  3. Add a config lint/CI check that artifact durations are > 0.
  4. 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

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.

Related errors


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