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

  1. Check the path is correct relative to the process working directory — print os.Getwd() and use an absolute path.
  2. Verify the file exists and is readable: ls -l / cat the file as the same user running the service.
  3. Ensure the file is included in the container image / deployment artifact and not just on the dev machine.
  4. 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

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


AI-assisted analysis of gofr-dev/gofr@187eb24962 (2026-09-01). Data as JSON: /api/errors/541ea2f512c587e3. Report an issue: GitHub.