thanos-io/thanos · error

unable to load config file

Error message

unable to load config file

What it means

Wrapper raised in newEndpointConfigProvider when the initial parse() of the endpoint config file fails. It combines all content-load failures (I/O and unmarshal) under a single message 'unable to load config file' and prevents StoreAPI endpoint set construction. The underlying parse error (with file path) is chained.

Solutions

  1. Ensure the endpoint config file exists and is readable at the path given to --endpoint-config before starting Thanos.
  2. Fix YAML syntax/types in the file (see the chained parse error for the exact path).
  3. If you don't need file-based endpoints, use static --endpoint flags instead so a NopConfig is used.
  4. For k8s, add an init container or readiness gate ensuring the ConfigMap/Secret is mounted before Thanos starts.

Example fix

// before: starting query with missing file
// thanos query --endpoint-config=/etc/thanos/endpoints.yaml
// after: guard in startup script
// test -r /etc/thanos/endpoints.yaml || { echo 'endpoint config missing'; exit 1; }
// thanos query --endpoint-config=/etc/thanos/endpoints.yaml
Defensive patterns

Strategy: validation

Validate before calling

func ensureEndpointConfig(path string) error { if path == "" { return nil }; b, err := os.ReadFile(path); if err != nil { return err }; var c EndpointConfig; return yaml.Unmarshal(b, &c) }

Type guard

func configPresent(p string) bool { if p == "" { return true }; _, err := os.Stat(p); return err == nil }

Try / catch

res, err := newEndpointConfigProvider(logger, reg, configFile, ...)
if err != nil {
    if strings.Contains(err.Error(), "unable to load config file") { log.Fatalf("fix --endpoint-config: %v", err) }
    return err
}

Prevention

When it happens

Trigger: newEndpointConfigProvider is called with a configFile whose Content() fails (missing/unreadable file) or whose YAML cannot be unmarshaled into EndpointConfig; setupEndpointSet then fails at startup.

Common situations: Thanos Query started with --endpoint-config pointing to a nonexistent file; k8s projected volume not mounted yet at process start; malformed YAML in the config file.

Understand the failure class

Background: "Config file not found": what it means and how to fix it in docker-sync, Maven, Vagrant, Turborepo and other tools — this error's family across 60 libraries.

Related errors


AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07). Data as JSON: /api/errors/d1099dfea3143b29. Report an issue: GitHub.

Appendix: source

Thrown at cmd/thanos/endpointset.go:249

	staticEndpoints []string,
	staticEndpointGroups []string,
	staticStrictEndpoints []string,
	staticStrictEndpointGroups []string,
) (*endpointConfigProvider, error) {
	res := &endpointConfigProvider{
		endpoints:            staticEndpoints,
		endpointGroups:       staticEndpointGroups,
		strictEndpoints:      staticStrictEndpoints,
		strictEndpointGroups: staticStrictEndpointGroups,
	}

	if configFile == nil {
		configFile = extkingpin.NewNopConfig()
	}

	cfg, err := res.parse(configFile)
	if err != nil {
		return nil, errors.Wrapf(err, "unable to load config file")
	}
	res.addStaticEndpoints(&cfg)
	if err := validateEndpointConfig(&cfg); err != nil {
		return nil, errors.Wrapf(err, "unable to validate endpoints")
	}
	res.cfg = cfg

	// only static endpoints
	if len(configFile.Path()) == 0 {
		return res, nil
	}

	if err := extkingpin.PathContentReloader(context.Background(), configFile, logger, func() {
		res.mu.Lock()
		defer res.mu.Unlock()

		level.Info(logger).Log("msg", "reloading endpoint config")
		cfg, err := res.parse(configFile)

View on GitHub (pinned to 35b8b99117)