{"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/03255a9237b6eb32710f6bc4f2de9a675b99fe36/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 file-based authorization interceptor needs a policy file to read and watch, so an empty path is rejected up front rather than failing later.","triggerScenarios":"Calling NewFileWatcher(\"\", duration) or NewFileWatcherWithOptions with an unset PolicyFile, e.g. when the path is supposed to come from an env var or config flag that was not provided.","commonSituations":"Forgetting to wire a --authz-policy flag; env var not set in the deployment; config struct field left as the zero value; conditional that should set the file but did not run.","solutions":["Provide a non-empty policy file path to NewFileWatcher / NewFileWatcherWithOptions.","Read the path from an env var or flag and fail fast at startup if it is empty.","If authz is optional, skip constructing the interceptor entirely when no path is configured instead of passing \"\".","Validate the path exists before passing it (also avoids the later read-failed error)."],"exampleFix":"// before\naz, err := authz.NewFileWatcher(\"\", 10*time.Second)\n\n// after\npath := os.Getenv(\"GRPC_AUTHZ_POLICY\")\nif path == \"\" {\n    log.Fatal(\"GRPC_AUTHZ_POLICY must be set\")\n}\naz, err := authz.NewFileWatcher(path, 10*time.Second)","handlingStrategy":"validation","validationCode":"if strings.TrimSpace(options.PolicyFile) == \"\" {\n    return fmt.Errorf(\"authz policy file path is required\")\n}","typeGuard":null,"tryCatchPattern":"az, err := authz.NewFileWatcherWithOptions(opts)\nif err != nil {\n    if strings.Contains(err.Error(), \"policy file path is empty\") {\n        log.Fatal(\"set --authz-policy\")\n    }\n}","preventionTips":["Wire the policy path from an explicit flag/env var and fail fast if unset.","Skip authz setup when policy is optional instead of passing an empty string.","Add a startup config check listing required fields."],"tags":["go","grpc","authz","config"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}