temporalio/temporal · critical
unable to create dynamic config client: %w
Error message
unable to create dynamic config client: %w
What it means
ServerOptionsProvider creates the dynamic config client. When config.DynamicConfigClient is present it calls dynamicconfig.NewFileBasedClientWithMetrics, which loads and validates the dynamic config file; failure (parse error, bad value type, unreadable file) is wrapped as 'unable to create dynamic config client' and blocks startup. With no config block, a noop client is used instead.
Source
Thrown at temporal/fx.go:232
}
}
// EventLoggerProvider backs structured ("wide") events. Select the custom OTEL LoggerProvider
// if injected, else a no-op provider that discards events. A deployment opts in by injecting a
// provider via WithCustomEventLoggerProvider.
eventLoggerProvider := so.eventLoggerProvider
if eventLoggerProvider == nil {
eventLoggerProvider = lognoop.NewLoggerProvider()
}
// DynamicConfigClient
dcClient := so.dynamicConfigClient
if dcClient == nil {
dcConfig := so.config.DynamicConfigClient
if dcConfig != nil {
dcClient, err = dynamicconfig.NewFileBasedClientWithMetrics(dcConfig, logger, stopChan, metricHandler)
if err != nil {
return serverOptionsProvider{}, fmt.Errorf("unable to create dynamic config client: %w", err)
}
} else {
// noop client
logger.Info("Dynamic config client is not configured. Using default values.")
dcClient = dynamicconfig.NewNoopClient()
}
}
testHooks := testhooks.NewTestHooks()
if so.testHooks != nil {
testHooks = *so.testHooks
}
// TLSConfigProvider
tlsConfigProvider := so.tlsConfigProvider
if tlsConfigProvider == nil {
tlsConfigProvider, err = encryption.NewTLSConfigProviderFromConfig(so.config.Global.TLS, metricHandler, logger, nil)
if err != nil {View on GitHub (pinned to bde624efd1)
Solutions
- Fix the wrapped error's cause: correct the file path, YAML syntax, or invalid key/value in the dynamic config file
- Validate the file with the temporal server's dynamicconfig tooling (temporal server start-dev or dynamicconfig CLI validation)
- If no dynamic overrides are needed, remove the dynamicConfigClient block to use the noop client
- Check file permissions/mount correctness in containerized deployments
Example fix
// before dynamicConfigClient: filepath: "config/dynamicconfig/not_exist.yaml" // after dynamicConfigClient: filepath: "config/dynamicconfig/development.yaml"
Defensive patterns
Strategy: validation
Validate before calling
// validate the dynamic config file before server start
if _, err := os.Stat(dcFilepath); err != nil { log.Fatal(err) }
data, err := os.ReadFile(dcFilepath)
if err != nil { log.Fatal(err) }
var m map[string]any
if err := yaml.Unmarshal(data, &m); err != nil { log.Fatalf("invalid yaml: %v", err) } Prevention
- Validate the dynamic config file in CI and on deploy (parse + key/type check)
- Verify file mounts and permissions in Kubernetes before rollout
- Confirm value types match the server version's expectations for renamed keys
- Omit the dynamicConfigClient block entirely when no overrides are needed
When it happens
Trigger: dynamicconfig-client block pointing at a YAML file that does not exist, is not valid YAML, or contains a key/value that fails validation (e.g. wrong type for a known key).
Common situations: Wrong filepath in config; file mounted but empty or truncated in Kubernetes; YAML with tabs or type errors; a dynamic config key renamed after a server upgrade with a mismatched value type.
Related errors
- unable to create metrics handler: %w
- unable to create AWS HTTP client for Elasticsearch: %w
- unable to load config: %w
- could not load config file: %w
- only one of certData or certFile properties should be specif
AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01).
Data as JSON: /api/errors/a281340b757c88fa.
Report an issue: GitHub.