{"record":{"id":"41bf3c91c550bc82","repo":"nats-io/nats-server","slug":"fetch-timeout-v-is-too-smal","errorCode":null,"errorMessage":"Fetch timeout %v is too smal","messagePattern":"Fetch timeout (.+?) is too smal","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/accounts.go","lineNumber":4682,"sourceCode":"\t\tdr.Unlock()\n\t\tif srv == nil {\n\t\t\treturn _EMPTY_, err\n\t\t}\n\t\treturn srv.fetch(dr, name, to) // lookup from other server\n\t}\n}\n\nfunc (dr *DirAccResolver) Store(name, jwt string) error {\n\treturn dr.saveIfNewer(name, jwt)\n}\n\ntype DirResOption func(s *DirAccResolver) error\n\n// limits the amount of time spent waiting for an account fetch to complete\nfunc FetchTimeout(to time.Duration) DirResOption {\n\treturn func(r *DirAccResolver) error {\n\t\tif to <= time.Duration(0) {\n\t\t\treturn fmt.Errorf(\"Fetch timeout %v is too smal\", to)\n\t\t}\n\t\tr.fetchTimeout = to\n\t\treturn nil\n\t}\n}\n\nfunc (dr *DirAccResolver) apply(opts ...DirResOption) error {\n\tfor _, o := range opts {\n\t\tif err := o(dr); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc NewDirAccResolver(path string, limit int64, syncInterval time.Duration, delete deleteType, opts ...DirResOption) (*DirAccResolver, error) {\n\tif limit == 0 {\n\t\tlimit = math.MaxInt64","sourceCodeStart":4664,"sourceCodeEnd":4700,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/accounts.go#L4664-L4700","documentation":"Validation error from the FetchTimeout DirResOption: the caller passed a fetch timeout that is zero or negative, which would make account fetch waits meaningless. Note the message has a typo ('smal' instead of 'small').","triggerScenarios":"Passing FetchTimeout(0) or FetchTimeout(-1s) (any value <= time.Duration(0)) as a DirResOption when constructing a DirAccResolver, e.g. with the WithDirResolver/FetchTimeout option in server options.","commonSituations":"Programmatic server option construction where the timeout is derived from a config value that is unset (zero value) or parsed incorrectly as negative.","solutions":["Pass a strictly positive duration, e.g. FetchTimeout(2 * time.Second).","Clamp or default the configured value: if cfg <= 0 { cfg = 2 * time.Second } before applying the option.","Fix config parsing so unset values become a sensible default rather than 0.","Ignore the typo in the message — it indicates the duration value, not a different problem."],"exampleFix":"// before\nopts = append(opts, FetchTimeout(cfg.FetchTimeout)) // 0 when unset\n// after\nto := cfg.FetchTimeout\nif to <= 0 { to = 2 * time.Second }\nopts = append(opts, FetchTimeout(to))","handlingStrategy":"validation","validationCode":"to := cfg.FetchTimeout\nif to <= 0 {\n    return fmt.Errorf(\"FetchTimeout must be > 0, got %v\", to)\n}\nopts = append(opts, FetchTimeout(to))","typeGuard":"func validFetchTimeout(d time.Duration) bool { return d > 0 }","tryCatchPattern":"if err := FetchTimeout(to)(resolver); err != nil {\n    return fmt.Errorf(\"invalid fetch timeout %v: %w\", to, err)\n}","preventionTips":["Default zero-valued config durations to a sane positive value.","Validate all resolver options before applying them.","Remember the error message contains a typo ('smal'); match on prefix if filtering.","Use time.ParseDuration-safe parsing for config input."],"tags":["nats-server","account-resolver","configuration","timeout"],"backgroundTag":"invalid-config-value","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}