{"record":{"id":"c3172a5383320239","repo":"googleapis/mcp-toolbox","slug":"unable-to-parse-timeout-string-as-time-duration","errorCode":null,"errorMessage":"unable to parse Timeout string as time.Duration: %s","messagePattern":"unable to parse Timeout string as time\\.Duration: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/sources/http/http.go","lineNumber":91,"sourceCode":"\tTimeout                string            `yaml:\"timeout\"`\n\tDefaultHeaders         map[string]string `yaml:\"headers\"`\n\tQueryParams            map[string]string `yaml:\"queryParams\"`\n\tReturnFullError        bool              `yaml:\"returnFullError\"`\n\tDisableSslVerification bool              `yaml:\"disableSslVerification\"`\n\tAllowedIPRanges        []string          `yaml:\"allowedIpRanges\"`\n\tCustomBlockedIPRanges  []string          `yaml:\"customBlockedIpRanges\"`\n\tAllowPrivateNetworks   bool              `yaml:\"allowPrivateNetworks\"`\n}\n\nfunc (r Config) SourceConfigType() string {\n\treturn SourceType\n}\n\n// Initialize initializes an HTTP Source instance.\nfunc (r Config) Initialize(ctx context.Context, tracer trace.Tracer) (sources.Source, error) {\n\tduration, err := time.ParseDuration(r.Timeout)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"unable to parse Timeout string as time.Duration: %s\", err)\n\t}\n\n\tvar tr *http.Transport\n\tif defaultTr, ok := http.DefaultTransport.(*http.Transport); ok {\n\t\ttr = defaultTr.Clone()\n\t} else {\n\t\ttr = &http.Transport{}\n\t}\n\n\tlogger, err := util.LoggerFromContext(ctx)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"unable to get logger from ctx: %s\", err)\n\t}\n\n\tif r.DisableSslVerification {\n\t\ttr.TLSClientConfig = &tls.Config{\n\t\t\tInsecureSkipVerify: true,\n\t\t}","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/googleapis/mcp-toolbox/blob/8cc6e09de2ad7b8bffc77751799585a1401a48eb/internal/sources/http/http.go#L73-L109","documentation":"This error comes from the HTTP source's Initialize when time.ParseDuration cannot parse the configured Timeout string into a valid time.Duration. The Timeout field must be a Go duration string such as \"30s\", \"5m\", or \"1h30m\". A missing unit (e.g. \"30\") or garbage text makes parsing fail and the source aborts initialization.","triggerScenarios":"Config.Initialize calls time.ParseDuration(r.Timeout) and gets an error: Timeout set to \"30\" (no unit), \"seconds\", \"\", \"thirty seconds\", or any string outside Go's duration syntax.","commonSituations":"Copy-pasting a plain integer timeout from another tool's config; forgetting units like \"ms\" vs \"s\"; empty Timeout field in YAML; assuming the value is seconds by default.","solutions":["Set Timeout to a valid Go duration string, e.g. \"30s\" or \"2m\"","Remember the unit is mandatory: use \"500ms\" not \"500\"","Check the YAML config for the http source's `timeout:` key — remove quotes-irrelevant typos and stray characters"],"exampleFix":"// before\ntimeout: 30\n// after\ntimeout: 30s","handlingStrategy":"validation","validationCode":"func validTimeout(s string) bool {\n    _, err := time.ParseDuration(s)\n    return err == nil\n}\n// usage: if !validTimeout(cfg.Timeout) { fix config before Initialize }","typeGuard":null,"tryCatchPattern":"src, err := cfg.Initialize(ctx, tracer)\nif err != nil && strings.Contains(err.Error(), \"unable to parse Timeout\") {\n    log.Fatalf(\"bad timeout format in http source config: %v\", err)\n}","preventionTips":["Always include units in durations: \"30s\", \"5m\", \"500ms\"","Never use bare integers in the timeout field","Add a config pre-check with time.ParseDuration in CI/startup scripts"],"tags":["http","configuration","validation","duration"],"backgroundTag":"config-parse-error","analyzedSha":"8cc6e09de2ad7b8bffc77751799585a1401a48eb","analyzedAt":"2026-09-05T01:10:36.887Z","contentChangedAt":"2026-09-05T01:10:36.887Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}