temporalio/temporal · error
could not read config file: %s. error: %w
Error message
could not read config file: %s. error: %w
What it means
readConfigFile wraps os.ReadFile failures for an individual config file, including the path and underlying OS error. Config load fails fast: once the file list is known, every file must be readable to build the full Config. This is distinct from parse errors — the file exists in the list but its bytes could not be read.
Source
Thrown at common/config/loader.go:220
processedData, err := processConfigFile(data, filepath.Base(f))
if err != nil {
return err
}
err = yaml.Unmarshal(processedData, config)
if err != nil {
return err
}
}
validate := newValidator()
return validate.Validate(config)
}
func readConfigFile(path string) ([]byte, error) {
data, err := os.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("could not read config file: %s. error: %w", path, err)
}
return data, nil
}
// processConfigFile processes a config file, rendering it as a template if enabled
func processConfigFile(data []byte, filename string) ([]byte, error) {
// If the config file contains "enable-template" in a comment within the first 1KB, then
// we will treat the file as a template and render it.
templating, err := checkTemplatingEnabled(data)
if err != nil {
return nil, err
}
if !templating {
return data, nil
}
View on GitHub (pinned to bde624efd1)
Solutions
- Inspect the embedded OS error (error: %w) — e.g. permission denied vs no such file — and fix accordingly
- chmod/chown the file so the temporal process user can read it
- If the file is a broken symlink or directory, restore or remove it
- In Kubernetes, verify the ConfigMap volume mount actually materialized the expected files
Example fix
// before $ ls -l /etc/temporal/config/production.yaml lrwxrwxrwx ... production.yaml -> /mnt/missing/production.yaml // after $ rm production.yaml $ kubectl create configmap temporal-config --from-file=config/
Defensive patterns
Strategy: validation
Validate before calling
func canRead(path string) error {
f, err := os.Open(path)
if err != nil {
return err
}
return f.Close()
} Prevention
- Prefer real files over dangling symlinks in config dirs
- Watch for races with ConfigMap/Secret volume updates; retry load on transient read errors if applicable
- Run temporal under a user with read access to the mounted config files
When it happens
Trigger: load or loadLegacy -> readConfigFile(path) when the file listed by getConfigFiles disappears, is a directory, or lacks read permission; also symlinks pointing to nonexistent targets.
Common situations: Broken symlink in the config dir, a config file deleted/renamed between listing and reading (races in k8s ConfigMap mounts), read-permission denied for the process user, or a zone-specific file left as a directory by mistake.
Related errors
- unable to read client ca file
- unable to read client certificate file
- failed to get config files: %w
- requires a StartTime or CloseTime
- 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/b6d3e5fd67a67aa8.
Report an issue: GitHub.