temporalio/temporal · error

failed to get config files: %w

Error message

failed to get config files: %w

What it means

loadLegacy in the config loader gathers the ordered list of YAML files (base, env, zone overlays) via getConfigFiles. If listing/reading the config directory fails (e.g. stat/read errors or malformed pattern), the error is wrapped as "failed to get config files" and config loading aborts. This means temporal could not even determine which config files exist, before parsing any of them.

Source

Thrown at common/config/loader.go:191

//
//   base.yaml
//     env.yaml     -- where "environment" is one of the input parameters (e.g., "development")
//       env_az.yaml -- where "zone" is another input parameter

func (opts *loadOptions) loadLegacy(config any) error {
	stdlog.Printf("Loading config; env=%v,zone=%v,configDir=%v\n", opts.env, opts.zone, opts.configDir)
	if opts.env == "" {
		opts.env = envDevelopment
	}
	if opts.configDir == "" {
		opts.configDir = defaultConfigDir
	}

	stdlog.Printf("Loading config; env=%v,zone=%v,configDir=%v\n", opts.env, opts.zone, opts.configDir)

	files, err := getConfigFiles(opts.env, opts.configDir, opts.zone)
	if err != nil {
		return fmt.Errorf("failed to get config files: %w", err)
	}

	stdlog.Printf("Loading config files=%v\n", files)

	for _, f := range files {
		data, err := readConfigFile(f)
		if err != nil {
			return err
		}

		processedData, err := processConfigFile(data, filepath.Base(f))
		if err != nil {
			return err
		}

		err = yaml.Unmarshal(processedData, config)
		if err != nil {
			return err

View on GitHub (pinned to bde624efd1)

Solutions

  1. Verify the config directory path (configDir option / CONFIG_PATH env) exists and is readable by the temporal process
  2. Ensure config files follow the expected naming: base config, then env (and zone) files, e.g. development.yaml or production.yaml under the configured dir
  3. Fix filesystem permissions (chown/chmod) or remount the config volume
  4. Check the wrapped underlying error (%w) for the exact OS reason (no such file, permission denied, etc.)

Example fix

// before (cmd flag)
--config-dir /etc/temporal/confg   # typo
// after
--config-dir /etc/temporal/config
Defensive patterns

Strategy: validation

Validate before calling

if info, err := os.Stat(configDir); err != nil || !info.IsDir() {
	return fmt.Errorf("config dir %s missing or not a directory: %w", configDir, err)
}

Prevention

When it happens

Trigger: Calling LoadConfig/load -> loadLegacy with a configDir that does not exist, is unreadable (permissions), or where getConfigFiles encounters an OS error while resolving env/zone file paths.

Common situations: Wrong CONFIG_PATH/env var pointing at a missing directory, container image missing the /etc/temporal/config mount, permission denied after running as a non-root user, or typo'd configDir flag/zone name causing expected file paths to be unresolvable.

Related errors


AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01). Data as JSON: /api/errors/7d32e80aeb88ea4b. Report an issue: GitHub.