{"record":{"id":"bd711cd84488ac5d","repo":"grpc/grpc-go","slug":"policyfile-s-read-failed-v","errorCode":null,"errorMessage":"policyFile(%s) read failed: %v","messagePattern":"policyFile\\((.+?)\\) read failed: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"authz/grpc_authz_server_interceptors.go","lineNumber":175,"sourceCode":"\t\t\tlogger.Warningf(\"authorization policy reload status err: %v\", err)\n\t\t}\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\tticker.Stop()\n\t\t\treturn\n\t\tcase <-ticker.C:\n\t\t}\n\t}\n}\n\n// updateInternalInterceptor checks if the policy file that is watching has changed,\n// and if so, updates the internalInterceptor with the policy. Unlike the\n// constructor, if there is an error in reading the file or parsing the policy, the\n// previous internalInterceptors will not be replaced.\nfunc (i *FileWatcherInterceptor) updateInternalInterceptor() error {\n\tpolicyContents, err := os.ReadFile(i.options.PolicyFile)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"policyFile(%s) read failed: %v\", i.options.PolicyFile, err)\n\t}\n\tif bytes.Equal(i.policyContents, policyContents) {\n\t\treturn nil\n\t}\n\ti.policyContents = policyContents\n\tpolicyContentsString := string(policyContents)\n\tinterceptor, err := NewStatic(policyContentsString)\n\tif err != nil {\n\t\treturn err\n\t}\n\tatomic.StorePointer(&i.internalInterceptor, unsafe.Pointer(interceptor))\n\tlogger.Infof(\"authorization policy reload status: successfully loaded new policy %v\", policyContentsString)\n\tif i.options.OnPolicyUpdate != nil {\n\t\ti.options.OnPolicyUpdate(policyContentsString)\n\t}\n\treturn nil\n}\n","sourceCodeStart":157,"sourceCodeEnd":193,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/authz/grpc_authz_server_interceptors.go#L157-L193","documentation":"Returned by FileWatcherInterceptor.updateInternalInterceptor (grpc_authz_server_interceptors.go:175) when os.ReadFile fails on the policy file. It wraps the underlying OS error (e.g. not exist, permission denied). On initial construction this error propagates out of NewFileWatcherWithOptions; on later refresh ticks it is only logged as a warning and the last good policy is kept.","triggerScenarios":"The policy file path does not exist, is unreadable due to permissions, or the process lacks access at read time; a mounted volume/configmap is not yet attached when the server boots.","commonSituations":"Typo in the path; Kubernetes ConfigMap/Secret not mounted yet at startup; file owned by another user with no read bit; container filesystem mount misconfigured; file rotated/deleted under a running watcher.","solutions":["Verify the path is correct and the file is readable by the process user before constructing the watcher.","In Kubernetes, ensure the ConfigMap/Secret volume is mounted and use startup ordering/readiness to delay boot until present.","Fix filesystem permissions (chmod/chown) so the process can read the file.","If the file may be briefly absent, pre-create it or retry construction rather than crashing."],"exampleFix":"// before\naz, err := authz.NewFileWatcher(\"/etc/authz/policy.json\", 10*time.Second)\n// error: policyFile(/etc/authz/policy.json) read failed: open ...: no such file\n\n// after - verify existence first\npath := \"/etc/authz/policy.json\"\nif _, err := os.Stat(path); err != nil {\n    log.Fatalf(\"authz policy not accessible: %v\", err)\n}\naz, err := authz.NewFileWatcher(path, 10*time.Second)","handlingStrategy":"validation","validationCode":"if _, err := os.Stat(options.PolicyFile); err != nil {\n    return fmt.Errorf(\"authz policy file not readable: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"az, err := authz.NewFileWatcherWithOptions(opts)\nif err != nil && strings.Contains(err.Error(), \"read failed\") {\n    // retry after a short delay or fail with actionable message\n    return fmt.Errorf(\"policy file unreadable: %w\", err)\n}","preventionTips":["Verify the file exists and is readable by the process user at startup.","Ensure ConfigMaps/Secrets are mounted before the process reads them.","Set correct file ownership and permissions in your image/manifest."],"tags":["go","grpc","authz","filesystem","config"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}