{"record":{"id":"541ea2f512c587e3","repo":"gofr-dev/gofr","slug":"failed-to-read-rbac-config-file-s-w","errorCode":null,"errorMessage":"failed to read RBAC config file %s: %w","messagePattern":"failed to read RBAC config file (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/gofr/rbac/config.go","lineNumber":137,"sourceCode":"\tTracer trace.Tracer `json:\"-\" yaml:\"-\"`\n\n\t// Internal maps built from unified config (not in JSON/YAML)\n\t// These are populated by processUnifiedConfig()\n\trolePermissionsMap    map[string][]string         `json:\"-\" yaml:\"-\"`\n\tendpointPermissionMap map[string][]string         `json:\"-\" yaml:\"-\"` // Key: \"METHOD:/path\", Value: []permissions\n\tpublicEndpointsMap    map[string]bool             `json:\"-\" yaml:\"-\"` // Key: \"METHOD:/path\", Value: true if public\n\tendpointMap           map[string]*EndpointMapping `json:\"-\" yaml:\"-\"` // Key: \"METHOD:/path\", Value: endpoint object\n\tmuxRouter             *mux.Router                 `json:\"-\" yaml:\"-\"` // Used for mux pattern matching\n}\n\n// LoadPermissions loads RBAC configuration from a JSON or YAML file.\n// The file format is automatically detected based on the file extension.\n// Supported formats: .json, .yaml, .yml.\n// Dependencies (logger, metrics, tracer) are optional and can be set after loading.\nfunc LoadPermissions(path string, logger datasource.Logger, metrics container.Metrics, tracer trace.Tracer) (*Config, error) {\n\tdata, err := os.ReadFile(path)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to read RBAC config file %s: %w\", path, err)\n\t}\n\n\tvar config Config\n\n\t// Detect file format by extension\n\text := strings.ToLower(filepath.Ext(path))\n\tswitch ext {\n\tcase \".yaml\", \".yml\":\n\t\tif err := yaml.Unmarshal(data, &config); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to parse YAML config file %s: %w\", path, err)\n\t\t}\n\tcase \".json\", \"\":\n\t\tif err := json.Unmarshal(data, &config); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to parse JSON config file %s: %w\", path, err)\n\t\t}\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unsupported config file format: %s (supported: .json, .yaml, .yml): %w\", ext, errUnsupportedFormat)\n\t}","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/gofr-dev/gofr/blob/187eb24962502e91f1fee856230670958b66e89c/pkg/gofr/rbac/config.go#L119-L155","documentation":"This error is raised by rbac.LoadPermissions when os.ReadFile cannot read the RBAC permissions config file at the given path. The original filesystem error (not found, permission denied, is-a-directory, etc.) is wrapped with %w and the path is included, so the full message identifies which file could not be read and why. It fires before any parsing or format detection happens.","triggerScenarios":"Calling LoadPermissions(path, logger, metrics, tracer) or EnableRBAC with a path that does not exist, lacks read permission, points to a directory, or is on an unmounted volume.","commonSituations":"Wrong relative path because the process runs from a different working directory (container vs host); config file not copied into the Docker image; read permissions changed by deployment; using a directory path instead of a file path.","solutions":["Check the path is correct relative to the process working directory — print os.Getwd() and use an absolute path.","Verify the file exists and is readable: ls -l / cat the file as the same user running the service.","Ensure the file is included in the container image / deployment artifact and not just on the dev machine.","Confirm the path points to a file, not a directory, and fix filesystem permissions (chmod/chown)."],"exampleFix":"// before: relative path breaks when cwd differs\nperms, err := rbac.LoadPermissions(\"configs/rbac.yaml\", logger, metrics, tracer)\n// after: absolute or env-provided path with existence check\npath := os.Getenv(\"RBAC_CONFIG_PATH\") // e.g. /etc/app/rbac.yaml\nif _, err := os.Stat(path); err != nil {\n\tlog.Fatalf(\"rbac config missing: %v\", err)\n}\nperms, err := rbac.LoadPermissions(path, logger, metrics, tracer)","handlingStrategy":"validation","validationCode":"func rbacFileReadable(path string) error {\n\tinfo, err := os.Stat(path)\n\tif err != nil { return err }\n\tif info.IsDir() { return fmt.Errorf(\"%s is a directory\", path) }\n\tf, err := os.Open(path)\n\tif err != nil { return err }\n\treturn f.Close()\n}","typeGuard":null,"tryCatchPattern":"perms, err := rbac.LoadPermissions(path, logger, metrics, tracer)\nif err != nil {\n\treturn fmt.Errorf(\"cannot start: RBAC config unreadable: %w\", err)\n}","preventionTips":["Pass the config path via env var and validate with os.Stat at startup.","Verify the config file is included in Docker images and deploy artifacts.","Run the service under a user with read access to the config location.","Fail fast at boot with a clear message instead of silently starting without RBAC."],"tags":["rbac","config","filesystem","gofr"],"backgroundTag":"config-file-not-found","analyzedSha":"187eb24962502e91f1fee856230670958b66e89c","analyzedAt":"2026-09-01T20:34:54.554Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}