temporalio/temporal · error
could not load config file: %w
Error message
could not load config file: %w
What it means
Returned by serverOptions.loadConfig in temporal/server_options.go:115 when config.Load(WithConfigFile(...)) fails to load an explicit config file path. This wrapper is in turn wrapped by 'unable to load config'. Causes include unreadable file, YAML parse errors, or missing required top-level config sections.
Source
Thrown at temporal/server_options.go:115
err := so.validateConfig()
if err != nil {
return fmt.Errorf("config validation error: %w", err)
}
return nil
}
func (so *serverOptions) loadConfig() error {
if so.configFilePath != "" {
if so.env != "" || so.configDir != "" || so.zone != "" {
return errors.New("env, config, zone can not be set if configFilePath is set")
}
cfg, err := config.Load(
config.WithConfigFile(so.configFilePath),
)
if err != nil {
return fmt.Errorf("could not load config file: %w", err)
}
so.config = cfg
return nil
}
cfg, err := config.Load(
config.WithEnv(so.env),
config.WithConfigDir(so.configDir),
config.WithZone(so.zone),
)
if err != nil {
return fmt.Errorf("could not load config file: %w", err)
}
so.config = cfg
return nil
}
func (so *serverOptions) validateConfig() error {
if err := so.config.Validate(); err != nil {View on GitHub (pinned to bde624efd1)
Solutions
- Confirm the file exists and is readable by the process user (ls -l / permissions).
- Validate the YAML parses (e.g. yamllint) and matches the temporal server config schema.
- Check the innermost wrapped error from config.Load for the precise failure (parse vs missing key).
- If you only need to override part of the config, consider configDir+env layout instead of a single explicit file.
Example fix
// before
so := opts; // WithConfigFilePath("config.yaml") relative to a different working dir
// after
temporal.WithConfigFilePath("/absolute/path/to/config.yaml") // always use absolute paths in services Defensive patterns
Strategy: validation
Validate before calling
path := so.configFilePath
info, err := os.Stat(path)
if err != nil || info.IsDir() {
return fmt.Errorf("config file %q not readable", path)
}
if err := yaml.Unmarshal([]byte(mustRead(path)), &map[string]any{}); err != nil {
return fmt.Errorf("config file %q is not valid YAML: %w", path, err)
} Try / catch
if err := cfgLoaded(); err != nil {
if errors.Is(err, os.ErrNotExist) {
log.Fatalf("config file missing: %v", err)
}
return err
} Prevention
- Check file existence and readability at service entrypoint before NewServer.
- Use absolute paths and verify volumes are mounted in K8s/Docker.
- Lint YAML in CI to catch syntax errors before deploy.
When it happens
Trigger: Using temporal.WithConfigFilePath(path) with the temporal server options where path is nonexistent, unreadable (permissions), not valid YAML, or semantically incomplete per config.Load's requirements.
Common situations: Absolute path typo, Docker/K8s volume not mounted, file copied without the expected schema, YAML indentation errors, or using a config file from an incompatible Temporal version.
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
- unable to create dynamic config client: %w
- only one of certData or certFile properties should be specif
- failed to process config file %s: %w
- unable to create metrics handler: %w
- unable to create AWS HTTP client for Elasticsearch: %w
AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01).
Data as JSON: /api/errors/7c686b1c50b78c4a.
Report an issue: GitHub.