gofr-dev/gofr · error
failed to read RBAC config file %s: %w
Error message
failed to read RBAC config file %s: %w
What it means
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.
Source
Thrown at pkg/gofr/rbac/config.go:137
Tracer trace.Tracer `json:"-" yaml:"-"`
// Internal maps built from unified config (not in JSON/YAML)
// These are populated by processUnifiedConfig()
rolePermissionsMap map[string][]string `json:"-" yaml:"-"`
endpointPermissionMap map[string][]string `json:"-" yaml:"-"` // Key: "METHOD:/path", Value: []permissions
publicEndpointsMap map[string]bool `json:"-" yaml:"-"` // Key: "METHOD:/path", Value: true if public
endpointMap map[string]*EndpointMapping `json:"-" yaml:"-"` // Key: "METHOD:/path", Value: endpoint object
muxRouter *mux.Router `json:"-" yaml:"-"` // Used for mux pattern matching
}
// LoadPermissions loads RBAC configuration from a JSON or YAML file.
// The file format is automatically detected based on the file extension.
// Supported formats: .json, .yaml, .yml.
// Dependencies (logger, metrics, tracer) are optional and can be set after loading.
func LoadPermissions(path string, logger datasource.Logger, metrics container.Metrics, tracer trace.Tracer) (*Config, error) {
data, err := os.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("failed to read RBAC config file %s: %w", path, err)
}
var config Config
// Detect file format by extension
ext := strings.ToLower(filepath.Ext(path))
switch ext {
case ".yaml", ".yml":
if err := yaml.Unmarshal(data, &config); err != nil {
return nil, fmt.Errorf("failed to parse YAML config file %s: %w", path, err)
}
case ".json", "":
if err := json.Unmarshal(data, &config); err != nil {
return nil, fmt.Errorf("failed to parse JSON config file %s: %w", path, err)
}
default:
return nil, fmt.Errorf("unsupported config file format: %s (supported: .json, .yaml, .yml): %w", ext, errUnsupportedFormat)
}View on GitHub (pinned to 187eb24962)
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).
Example fix
// before: relative path breaks when cwd differs
perms, err := rbac.LoadPermissions("configs/rbac.yaml", logger, metrics, tracer)
// after: absolute or env-provided path with existence check
path := os.Getenv("RBAC_CONFIG_PATH") // e.g. /etc/app/rbac.yaml
if _, err := os.Stat(path); err != nil {
log.Fatalf("rbac config missing: %v", err)
}
perms, err := rbac.LoadPermissions(path, logger, metrics, tracer) Defensive patterns
Strategy: validation
Validate before calling
func rbacFileReadable(path string) error {
info, err := os.Stat(path)
if err != nil { return err }
if info.IsDir() { return fmt.Errorf("%s is a directory", path) }
f, err := os.Open(path)
if err != nil { return err }
return f.Close()
} Try / catch
perms, err := rbac.LoadPermissions(path, logger, metrics, tracer)
if err != nil {
return fmt.Errorf("cannot start: RBAC config unreadable: %w", err)
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "Config file not found": what it means and how to fix it in docker-sync, Maven, Vagrant, Turborepo and other tools — this error's family across 60 libraries.
Related errors
- unsupported config file format
- endpoint must specify requiredPermissions (or be public)
- wildcard pattern '/*' is not supported, use mux patterns ins
- regex pattern '^...$' is not supported, use mux patterns ins
- regex pattern is not supported, use mux patterns instead
AI-assisted analysis of gofr-dev/gofr@187eb24962 (2026-09-01).
Data as JSON: /api/errors/541ea2f512c587e3.
Report an issue: GitHub.