hashicorp/nomad · error
error parsing GCSTimeout: %w
Error message
error parsing GCSTimeout: %w
What it means
ArtifactConfigFromAgent parses GCSTimeout with time.ParseDuration to produce a time.Duration for GCS artifact downloads. A non-duration string cannot be converted, so the wrapped parse error is returned with this message and the ArtifactConfig is not built.
Source
Thrown at client/config/artifact.go:50
SetEnvironmentVariables string
}
// ArtifactConfigFromAgent creates a new internal readonly copy of the client
// agent's ArtifactConfig. The config should have already been validated.
func ArtifactConfigFromAgent(c *config.ArtifactConfig) (*ArtifactConfig, error) {
httpReadTimeout, err := time.ParseDuration(*c.HTTPReadTimeout)
if err != nil {
return nil, fmt.Errorf("error parsing HTTPReadTimeout: %w", err)
}
httpMaxSize, err := humanize.ParseBytes(*c.HTTPMaxSize)
if err != nil {
return nil, fmt.Errorf("error parsing HTTPMaxSize: %w", err)
}
gcsTimeout, err := time.ParseDuration(*c.GCSTimeout)
if err != nil {
return nil, fmt.Errorf("error parsing GCSTimeout: %w", err)
}
gitTimeout, err := time.ParseDuration(*c.GitTimeout)
if err != nil {
return nil, fmt.Errorf("error parsing GitTimeout: %w", err)
}
hgTimeout, err := time.ParseDuration(*c.HgTimeout)
if err != nil {
return nil, fmt.Errorf("error parsing HgTimeout: %w", err)
}
s3Timeout, err := time.ParseDuration(*c.S3Timeout)
if err != nil {
return nil, fmt.Errorf("error parsing S3Timeout: %w", err)
}
decompressionSizeLimit, err := humanize.ParseBytes(*c.DecompressionSizeLimit)View on GitHub (pinned to 482b49bf1a)
Solutions
- Append a valid Go duration unit to the value: use "30s", "5m", "1h30m" instead of a bare number
- Check the rendered Nomad agent config for the gcs_timeout value and ensure it is non-empty and unit-suffixed
- Pre-validate with time.ParseDuration in the code that assembles the config to fail earlier with context
Example fix
// before gcs_timeout = "120" // after gcs_timeout = "120s"
Defensive patterns
Strategy: validation
Validate before calling
if _, err := time.ParseDuration(*c.GCSTimeout); err != nil {
return fmt.Errorf("invalid gcs_timeout %q: %w", *c.GCSTimeout, err)
} Type guard
func validDuration(s *string) bool { if s == nil { return false }; _, err := time.ParseDuration(*s); return err == nil } Try / catch
cfg, err := config.ArtifactConfigFromAgent(agentCfg)
if err != nil {
if strings.Contains(err.Error(), "error parsing GCSTimeout") {
return fmt.Errorf("gcs_timeout must be a Go duration like 30s: %w", err)
}
return err
} Prevention
- Always include a unit in duration strings: "30s", "5m", "1h" — never a bare number
- Run nomad agent config validation before deploying
- Check templated configs for empty rendered values
When it happens
Trigger: Calling ArtifactConfigFromAgent when the agent ArtifactConfig's GCSTimeout points to a string like "30", "30sec", "thirty seconds", "" or "1h30m" misspellings that time.ParseDuration rejects.
Common situations: gcs_timeout set in the Nomad client artifact config block without a time unit (e.g. "30" instead of "30s"); values sourced from environment variables or templates that render empty; hand-written configs in tests.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- error parsing HTTPMaxSize: %w
- error parsing GitTimeout: %w
- error parsing HgTimeout: %w
- error parsing S3Timeout: %w
- error parsing HTTPReadTimeout: %w
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/014c341dd9767c8f.
Report an issue: GitHub.