temporalio/temporal · error
config validation error: %w
Error message
config validation error: %w
What it means
Returned by serverOptions.loadAndValidate in temporal/server_options.go:100 when the loaded config fails validation. Wrapping covers two sources: config.Config.Validate() failures (structural/semantic checks on persistence, services, etc.) and the check that every requested service name exists in config.Services. The server refuses to start with an internally inconsistent configuration even if the YAML parsed successfully.
Source
Thrown at temporal/server_options.go:100
}
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),
)
if err != nil {
return fmt.Errorf("could not load config file: %w", err)
}
so.config = cfg
return nilView on GitHub (pinned to bde624efd1)
Solutions
- Read the wrapped cause: if it names a service, add that service under the 'services' key of your config (or drop it from the requested service list via ServerOption).
- If the cause is from Config.Validate(), fix the specific field it reports (commonly persistence/datastores or global settings).
- Compare your config against the upstream config_template.yaml for the same Temporal version to find missing required sections.
- Ensure the services map in config has an entry for each of frontend, history, matching, worker that your server options request.
Example fix
// config.yaml before — worker requested by options but missing
services:
frontend:
rpc:
grpcPort: 7233
history:
rpc:
grpcPort: 7234
// after — added the missing service block
services:
frontend:
rpc:
grpcPort: 7233
history:
rpc:
grpcPort: 7234
worker:
rpc:
grpcPort: 7239 Defensive patterns
Strategy: validation
Validate before calling
// Pre-check every requested service exists in the config's services map
for _, svc := range []string{"frontend", "history", "matching", "worker"} {
if _, ok := cfg.Services[svc]; !ok {
return fmt.Errorf("service %q missing from config services map", svc)
}
} Try / catch
if err := server.Start(); err != nil {
if strings.Contains(err.Error(), "config validation error") {
log.Fatalf("invalid config: %v", err)
}
return err
} Prevention
- Keep the services section of your config in sync with the services your server options request.
- Diff your config against config_template.yaml when upgrading Temporal versions.
- Run config.Validate()-equivalent checks in a preflight/CI step before deployment.
When it happens
Trigger: temporal.NewServer(...) after config loads OK but: (a) Config.Validate() rejects the config (e.g. missing persistence setup, invalid DB config), or (b) a service requested via temporal.WithFrontendService/WithHistoryService/WithMatchingService/WithWorkerService/WithService (or DefaultsServiceNames) is absent from the 'services' section of the config file.
Common situations: Trimmed-down config files that omit a service section while the server was asked to run that service; upgrading Temporal and the config no longer satisfying new Validate() rules; hand-edited YAML where a services entry was renamed or deleted.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- %q service is missing in config
- env, config, zone can not be set if configFilePath is set
- unable to load config: %w
- only one of certData or certFile properties should be specif
- batchParams is nil
AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01).
Data as JSON: /api/errors/39307f91f02d7492.
Report an issue: GitHub.