benbjohnson/litestream · error · ErrConfigFileNotFound

%w: %s

Error message

%w: %s

What it means

OpenConfigFile wraps the failure to open the config file: when os.Open fails because the file does not exist, it returns fmt.Errorf("%w: %s", ErrConfigFileNotFound, filename), so callers can match errors.Is(err, litestream.ErrConfigFileNotFound) (as in main.go where it prints 'open <file>: no such file or directory'-style guidance). This indicates the -config path passed on the command line cannot be found.

Source

Thrown at cmd/litestream/main.go:608

			return dbConfig
		}
	}
	return nil
}

// OpenConfigFile opens a configuration file and returns a reader.
// Expands the filename path if needed.
func OpenConfigFile(filename string) (io.ReadCloser, error) {
	// Expand filename, if necessary.
	filename, err := expand(filename)
	if err != nil {
		return nil, err
	}

	// Open configuration file.
	f, err := os.Open(filename)
	if os.IsNotExist(err) {
		return nil, fmt.Errorf("%w: %s", ErrConfigFileNotFound, filename)
	} else if err != nil {
		return nil, err
	}

	return f, nil
}

// ReadConfigFile unmarshals config from filename. Expands path if needed.
// If expandEnv is true then environment variables are expanded in the config.
func ReadConfigFile(filename string, expandEnv bool) (Config, error) {
	f, err := OpenConfigFile(filename)
	if err != nil {
		return DefaultConfig(), err
	}
	defer f.Close()

	return ParseConfig(f, expandEnv)
}

View on GitHub (pinned to 4ed7a308f6)

Solutions

  1. Check the path passed to -config with `ls <path>` and fix typos.
  2. Use an absolute path (or run from the directory containing the config).
  3. Create the config file if it does not exist yet (`litestream.yml`).

Example fix

// before
litestream -config ./litestream-prod.yml
// after
litestream -config /etc/litestream/litestream.yml
Defensive patterns

Strategy: try-catch

Validate before calling

if _, err := os.Stat(configPath); os.IsNotExist(err) {
    return fmt.Errorf("config file %q does not exist", configPath)
}

Try / catch

if err := run(); err != nil {
    if errors.Is(err, litestream.ErrConfigFileNotFound) {
        log.Fatalf("config file missing: use -config <path>")
    }
}

Prevention

When it happens

Trigger: Running `litestream -config /path/to.yml` where /path/to.yml does not exist; OpenConfigFile is called from ReadConfigFile during startup.

Common situations: Typo in the config path; running from the wrong working directory with a relative path; config file deleted or never created; systemd unit pointing at a stale 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 benbjohnson/litestream@4ed7a308f6 (2026-09-06). Data as JSON: /api/errors/5256bf64a00f0809. Report an issue: GitHub.