{"record":{"id":"319d20222a6dd8ee","repo":"hashicorp/nomad","slug":"error-parsing-s3timeout-w","errorCode":null,"errorMessage":"error parsing S3Timeout: %w","messagePattern":"error parsing S3Timeout: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/config/artifact.go","lineNumber":65,"sourceCode":"\n\tgcsTimeout, err := time.ParseDuration(*c.GCSTimeout)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error parsing GCSTimeout: %w\", err)\n\t}\n\n\tgitTimeout, err := time.ParseDuration(*c.GitTimeout)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error parsing GitTimeout: %w\", err)\n\t}\n\n\thgTimeout, err := time.ParseDuration(*c.HgTimeout)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error parsing HgTimeout: %w\", err)\n\t}\n\n\ts3Timeout, err := time.ParseDuration(*c.S3Timeout)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error parsing S3Timeout: %w\", err)\n\t}\n\n\tdecompressionSizeLimit, err := humanize.ParseBytes(*c.DecompressionSizeLimit)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error parsing DecompressionLimitSize: %w\", err)\n\t}\n\n\treturn &ArtifactConfig{\n\t\tHTTPReadTimeout:               httpReadTimeout,\n\t\tHTTPMaxBytes:                  int64(httpMaxSize),\n\t\tGCSTimeout:                    gcsTimeout,\n\t\tGitTimeout:                    gitTimeout,\n\t\tHgTimeout:                     hgTimeout,\n\t\tS3Timeout:                     s3Timeout,\n\t\tDecompressionLimitFileCount:   *c.DecompressionFileCountLimit,\n\t\tDecompressionLimitSize:        int64(decompressionSizeLimit),\n\t\tDisableArtifactInspection:     *c.DisableArtifactInspection,\n\t\tDisableFilesystemIsolation:    *c.DisableFilesystemIsolation,","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/client/config/artifact.go#L47-L83","documentation":"In ArtifactConfigFromAgent, the agent's artifact S3Timeout string cannot be parsed by time.ParseDuration, so the artifact fetcher config cannot be built. Indicates a malformed duration value in the agent's artifact config block.","triggerScenarios":"Calling ArtifactConfigFromAgent when S3Timeout is a bare number (\"120\"), unsupported unit (\"2hrs\"), empty string, or otherwise rejected by time.ParseDuration.","commonSituations":"s3_timeout misconfigured in the Nomad client artifact block; values injected from environment variables without units; templated configs where a variable failed to render, leaving an empty string.","solutions":["Correct s3_timeout to a valid Go duration such as \"2m\" or \"120s\"","Verify the rendered agent config to ensure the value is non-empty and unit-suffixed","Add time.ParseDuration validation in config-generation tooling to catch this before agent startup"],"exampleFix":"// before\ns3_timeout = \"120\"\n// after\ns3_timeout = \"120s\"","handlingStrategy":"validation","validationCode":"if _, err := time.ParseDuration(*c.S3Timeout); err != nil {\n    return fmt.Errorf(\"invalid s3_timeout %q: %w\", *c.S3Timeout, err)\n}","typeGuard":"func validDuration(s *string) bool { if s == nil { return false }; _, err := time.ParseDuration(*s); return err == nil }","tryCatchPattern":"cfg, err := config.ArtifactConfigFromAgent(agentCfg)\nif err != nil {\n    if strings.Contains(err.Error(), \"error parsing S3Timeout\") {\n        return fmt.Errorf(\"s3_timeout must be a Go duration like 2m: %w\", err)\n    }\n    return err\n}","preventionTips":["Include units in s3_timeout values (\"2m\", \"120s\")","Catch empty env-injected values with a default before building config","Run config validation as part of CI for generated agent configs"],"tags":["config","parsing","duration","go"],"backgroundTag":"invalid-duration-or-size-config","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}