ory/hydra · error

file loader disabled

Error message

file loader disabled

What it means

oryx/osx.readFile (reached via RestrictedReadFile / ReadFileFromAllSources) parses the source string as a URL; when the scheme is empty (a plain local path) it consults the o.disableFileLoader option. If file loading has been disabled on the Options, it returns errors.New("file loader disabled") instead of touching the local filesystem. This is a deliberate security guard so restricted contexts cannot read arbitrary local files.

Source

Thrown at oryx/osx/file.go:157

// - WithDisabledFileLoader
// - WithDisabledHTTPLoader
// - WithDisabledBase64Loader
// - WithBase64Encoding
// - WithHTTPClient
func ReadFileFromAllSources(source string, opts ...Option) (bytes []byte, err error) {
	return readFile(source, newOptions().apply(opts))
}

func readFile(source string, o *options) (bytes []byte, err error) {
	parsed, err := url.Parse(source)
	if err != nil {
		return nil, errors.Wrap(err, "failed to parse URL")
	}

	switch parsed.Scheme {
	case "":
		if o.disableFileLoader {
			return nil, errors.New("file loader disabled")
		}

		//#nosec G304 -- false positive
		bytes, err = os.ReadFile(source)
		if err != nil {
			return nil, errors.Wrap(err, "unable to read the file")
		}
	case "file":
		if o.disableFileLoader {
			return nil, errors.New("file loader disabled")
		}

		//#nosec G304 -- false positive
		bytes, err = os.ReadFile(parsed.Host + parsed.Path)
		if err != nil {
			return nil, errors.Wrap(err, "unable to read the file")
		}
	case "http", "https":

View on GitHub (pinned to 4174065ffb)

Solutions

  1. Remove the DisableFileLoader option from the Options used to construct the reader, if local paths are legitimate in your deployment
  2. Change the source to a URL scheme that is still enabled (e.g. http(s)://) and serve the file over HTTP(S)
  3. Pre-load the file yourself and pass its bytes/content directly instead of a path
  4. Audit who set disableFileLoader (env/config wiring) — in restricted environments the error is intended behavior; move the file to an allowed source

Example fix

// before
opts.DisableFileLoader(true)
data, err := osx.RestrictedReadFile("/etc/app/config.yaml") // error: file loader disabled
// after
opts.DisableFileLoader(false) // or omit the option
data, err := osx.RestrictedReadFile("/etc/app/config.yaml")
Defensive patterns

Strategy: try-catch

Type guard

func isLocalPath(source string) bool {
	u, err := url.Parse(source)
	return err == nil && u.Scheme == ""
}

Try / catch

data, err := osx.RestrictedReadFile(source)
if err != nil {
	if err.Error() == "file loader disabled" {
		// re-enable the loader or fetch via an enabled scheme
	}
	return err
}

Prevention

When it happens

Trigger: Calling RestrictedReadFile or ReadFileFromAllSources with a bare path (no scheme, e.g. "/etc/config.yaml" or "./data.json") while the options were created with DisableFileLoader(true) (or equivalent option) set.

Common situations: Hardened/embedded deployments that disable the file loader for safety but then a config template or default flag still points at a local path; switching data sources from remote URLs to local files without re-enabling the loader.

Related errors


AI-assisted analysis of ory/hydra@4174065ffb (2026-09-03). Data as JSON: /api/errors/3c2d04e68c792e9b. Report an issue: GitHub.