{"record":{"id":"d2c730139f8e9227","repo":"grpc/grpc-go","slug":"authz-authorization-policy-file-path-is-empty","errorCode":null,"errorMessage":"authz: authorization policy file path is empty","messagePattern":"authz: authorization policy file path is empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"authz/grpc_authz_server_interceptors.go","lineNumber":137,"sourceCode":"}\n\n// NewFileWatcher returns a new FileWatcherInterceptor from a policy file\n// 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 {","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/grpc/grpc-go/blob/0c51461d27177d997e14c642fe18c11668fc09a3/authz/grpc_authz_server_interceptors.go#L119-L155","documentation":"Returned by authz.NewFileWatcherWithOptions (grpc_authz_server_interceptors.go:137) when FileWatcherOptions.PolicyFile is the empty string. The FileWatcher interceptor needs a file path to read the JSON authorization policy from on startup and on each refresh tick, so an empty path is rejected immediately and no watcher goroutine is started.","triggerScenarios":"Calling NewFileWatcher(\"\") or NewFileWatcherWithOptions with an unset PolicyFile field; reading the path from an env var or flag that defaulted to empty; constructing the interceptor before configuration loading completes.","commonSituations":"Flag/env-driven config where the policy path was not supplied in a given environment; wiring code that builds the interceptor unconditionally and supplies the path later; silent default of an empty string.","solutions":["Provide a non-empty policy file path in FileWatcherOptions.PolicyFile (or the first arg to NewFileWatcher).","Resolve the path from config/flag/env and fail application startup early if it is unset, before constructing the interceptor.","If you do not want file-based policy, use authz.NewStatic(policyJSON) instead of the file watcher."],"exampleFix":"// before\nfw, err := authz.NewFileWatcher(policyPath, 10*time.Second)\n\n// after\nif policyPath == \"\" {\n    log.Fatal(\"AUTHZ_POLICY_FILE is required\")\n}\nfw, err := authz.NewFileWatcher(policyPath, 10*time.Second)","handlingStrategy":"validation","validationCode":"opts := authz.FileWatcherOptions{PolicyFile: policyPath, RefreshDuration: refresh}\nif opts.PolicyFile == \"\" {\n    log.Fatal(\"authz: policy file path must be set\")\n}\nfw, err := authz.NewFileWatcherWithOptions(opts)","typeGuard":null,"tryCatchPattern":"fw, err := authz.NewFileWatcherWithOptions(opts)\nif err != nil {\n    if strings.Contains(err.Error(), \"policy file path is empty\") {\n        // supply PolicyFile and reconstruct\n    }\n}","preventionTips":["Fail fast at startup if the policy path env/flag is empty.","Prefer absolute paths for the policy file.","Use NewStatic if you do not need file-based reload."],"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"}