{"record":{"id":"5a2e57ff75c667dd","repo":"grpc/grpc-go","slug":"authz-requires-refresh-interval-v-greater-than","errorCode":null,"errorMessage":"authz: requires refresh interval(%v) greater than 0s","messagePattern":"authz: requires refresh interval\\((.+?)\\) greater than 0s","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"authz/grpc_authz_server_interceptors.go","lineNumber":140,"sourceCode":"// that contains JSON string of authorization policy and a refresh duration to\n// specify the amount of time between policy refreshes.\nfunc NewFileWatcher(file string, duration time.Duration) (*FileWatcherInterceptor, error) {\n\treturn NewFileWatcherWithOptions(FileWatcherOptions{PolicyFile: file, RefreshDuration: duration, OnPolicyUpdate: nil})\n}\n\n// NewFileWatcherWithOptions returns a new FileWatcherInterceptor from a set of\n// options.\n//\n// # Experimental\n//\n// Notice: This API is EXPERIMENTAL and may be changed or removed in a\n// later release.\nfunc NewFileWatcherWithOptions(options FileWatcherOptions) (*FileWatcherInterceptor, error) {\n\tif options.PolicyFile == \"\" {\n\t\treturn nil, fmt.Errorf(\"authz: authorization policy file path is empty\")\n\t}\n\tif options.RefreshDuration <= time.Duration(0) {\n\t\treturn nil, fmt.Errorf(\"authz: requires refresh interval(%v) greater than 0s\", options.RefreshDuration)\n\t}\n\ti := &FileWatcherInterceptor{options: options}\n\tif err := i.updateInternalInterceptor(); err != nil {\n\t\treturn nil, err\n\t}\n\tctx, cancel := context.WithCancel(context.Background())\n\ti.cancel = cancel\n\t// Create a background go routine for policy refresh.\n\tgo i.run(ctx)\n\treturn i, nil\n}\n\nfunc (i *FileWatcherInterceptor) run(ctx context.Context) {\n\tticker := time.NewTicker(i.options.RefreshDuration)\n\tfor {\n\t\tif err := i.updateInternalInterceptor(); err != nil {\n\t\t\tlogger.Warningf(\"authorization policy reload status err: %v\", err)\n\t\t}","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/grpc/grpc-go/blob/0c51461d27177d997e14c642fe18c11668fc09a3/authz/grpc_authz_server_interceptors.go#L122-L158","documentation":"Returned by authz.NewFileWatcherWithOptions (grpc_authz_server_interceptors.go:140) when FileWatcherOptions.RefreshDuration is <= 0. The interceptor spawns a background goroutine (run, line 153) that ticks on RefreshDuration via time.NewTicker to re-read the policy file; a zero or negative duration is an invalid ticker interval and is rejected before the goroutine starts.","triggerScenarios":"Calling NewFileWatcher(file, 0) or NewFileWatcherWithOptions with RefreshDuration unset (defaults to 0 because time.Duration zero value is 0); passing a negative duration; computing the interval from config that yielded 0.","commonSituations":"Forgetting to set RefreshDuration when using NewFileWatcherWithOptions; env-driven interval parsed as 0 on parse failure; tests that pass 0 for convenience.","solutions":["Set a positive RefreshDuration, e.g. 10*time.Second or any interval appropriate to how often your policy file changes.","If you do not want periodic reload, use authz.NewStatic (a one-shot static policy) rather than the file watcher.","Validate the parsed interval before constructing the interceptor and fail fast with a clear message."],"exampleFix":"// before\nfw, err := authz.NewFileWatcher(\"/etc/grpc/policy.json\", 0)\n\n// after\nfw, err := authz.NewFileWatcher(\"/etc/grpc/policy.json\", 30*time.Second)","handlingStrategy":"validation","validationCode":"if refresh <= 0 {\n    refresh = 30 * time.Second // sane default\n}\nfw, err := authz.NewFileWatcher(policyPath, refresh)","typeGuard":null,"tryCatchPattern":"fw, err := authz.NewFileWatcher(policyPath, refresh)\nif err != nil {\n    if strings.Contains(err.Error(), \"refresh interval\") {\n        // set a positive duration and reconstruct\n    }\n}","preventionTips":["Always pass a positive RefreshDuration to the file watcher.","Use NewStatic if you do not want periodic reload.","Validate interval parsed from config before constructing the interceptor."],"tags":["grpc","authz","config","go"],"backgroundTag":null,"analyzedSha":"0c51461d27177d997e14c642fe18c11668fc09a3","analyzedAt":"2026-08-11T14:49:15.055Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}