temporalio/temporal · error
unable to load config: %w
Error message
unable to load config: %w
What it means
This error is returned by serverOptions.loadAndValidate in the temporal server SDK when loading the server configuration fails (temporal/server_options.go:94). It wraps the underlying error from loadConfig, which itself loads YAML config files via common/config.Load. It is thrown because the server cannot start without a valid, fully-loaded configuration, so it aborts before validation. The wrapped message (typically "could not load config file: ...") identifies the actual cause.
Source
Thrown at temporal/server_options.go:94
}
for _, opt := range opts {
opt.apply(so)
}
return so
}
func (so *serverOptions) loadAndValidate() error {
for serviceName := range so.serviceNames {
if !slices.Contains(Services, string(serviceName)) {
return fmt.Errorf("invalid service %q in service list %v", serviceName, so.serviceNames)
}
}
if so.config == nil {
err := so.loadConfig()
if err != nil {
return fmt.Errorf("unable to load config: %w", err)
}
}
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),View on GitHub (pinned to bde624efd1)
Solutions
- Read the wrapped cause after 'unable to load config: ' and fix that root error first (missing file, bad YAML, invalid path).
- Verify the file passed to temporal.WithConfigFilePath exists and is valid YAML (temporal server config format with top-level keys like persistence, services, global).
- If using WithConfigDir/WithEnv/WithZone, confirm <configDir>/<env>.yaml (or base.yaml + <env>.yaml) exists; default configDir is ./config and default env is 'development'.
- Do not set Env/ConfigDir/Zone together with ConfigFilePath — that yields a distinct 'env, config, zone can not be set if configFilePath is set' error wrapped here.
- Alternatively pass a fully built config programmatically so config loading is skipped entirely.
Example fix
// before
server, err := temporal.NewServer(
temporal.WithConfigFilePath("/etc/temporal/config.yaml"), // file does not exist
)
// after
server, err := temporal.NewServer(
temporal.WithConfigFilePath("/etc/temporal/config/config_template.yaml"), // verified path
) Defensive patterns
Strategy: validation
Validate before calling
path := "/etc/temporal/config/config_template.yaml"
if _, err := os.Stat(path); err != nil {
return fmt.Errorf("config file %s missing before starting server: %w", path, err)
} Try / catch
server, err := temporal.NewServer(opts...)
if err != nil {
var cfgErr interface{ Unwrap() error }
if strings.Contains(err.Error(), "unable to load config") {
log.Fatalf("config load failed: %v", err) // inspect wrapped cause
}
return err
} Prevention
- Mount/ship the config directory with your binary and assert its presence at container startup.
- Use absolute config file paths in services/containers.
- Validate config files in CI (yamllint + temporal server config schema).
- Never mix WithConfigFilePath with WithEnv/WithConfigDir/WithZone.
When it happens
Trigger: Calling temporal.NewServer / temporal.NewServerFgBackgroundService (which calls loadAndValidate) with options where so.config is nil and config.Load fails: e.g. WithConfigFilePath pointing at a nonexistent/malformed YAML file, or WithConfigDir/WithEnv/WithZone resolving to a missing config file, or an env/configDir/zone combined with configFilePath.
Common situations: Typo'd or missing config file path, running the server in a container without mounting /etc/temporal/config, using an env name (development/production/docker) whose config directory does not exist, YAML syntax errors, or accidentally setting both ConfigFilePath and Env.
Related errors
- missing current cluster metadata under clusterMetadata.Clust
- unable to create metrics handler: %w
- unable to create dynamic config client: %w
- unable to create AWS HTTP client for Elasticsearch: %w
- config validation error: %w
AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01).
Data as JSON: /api/errors/9fbfa72b4a4635b8.
Report an issue: GitHub.