thanos-io/thanos · error
unable to load config content
Error message
unable to load config content: %s
What it means
This error is raised when the endpoint config file's content cannot be read from disk (configFile.Content() fails) while parsing endpointset configuration. Thanos wraps the underlying I/O error with the config file path so operators know which file failed. It aborts building the endpoint config provider.
Solutions
- Verify the file exists at the exact path reported in the error (ls -l) and is readable by the Thanos process user.
- Fix mount/secret setup so the config file is present at startup (e.g., correct ConfigMap volume mount path).
- If using the nop/static endpoints mode, ensure no endpoint-config flag is passed so a NopConfig is used instead.
- Check fsnotify/watcher support on the filesystem (NFS, tmpfs) — fall back to static --endpoint flags if watching is unreliable.
Example fix
// before: file may not exist
content, err := configFile.Content()
if err != nil { return EndpointConfig{}, errors.Wrapf(err, "unable to load config content: %s", configFile.Path()) }
// after: guard with an existence check before parse
if _, statErr := os.Stat(configFile.Path()); os.IsNotExist(statErr) {
return EndpointConfig{}, errors.Errorf("endpoint config file does not exist: %s", configFile.Path())
}
content, err := configFile.Content() Defensive patterns
Strategy: validation
Validate before calling
func canReadConfig(p string) error { fi, err := os.Stat(p); if err != nil { return err }; if fi.IsDir() { return fmt.Errorf("%s is a directory", p) }; f, err := os.Open(p); if err != nil { return err }; return f.Close() } Type guard
func fileReadable(p string) bool { f, err := os.Open(p); if err != nil { return false }; _ = f.Close(); return true } Try / catch
cfg, err := provider.parse(configFile)
if err != nil {
var pathErr *os.PathError
if errors.As(err, &pathErr) { log.Fatalf("endpoint config unreadable: %s: %v", pathErr.Path, pathErr.Err) }
return err
} Prevention
- Pre-check file existence/readability at startup before passing to --endpoint-config.
- In k8s, verify ConfigMap/Secret mounts exist in the readiness probe.
- Keep endpoint config paths absolute and stable; avoid symlinks into volatile locations.
- Run Thanos with a service user that has read permission on the config.
When it happens
Trigger: Calling endpointConfigProvider.parse when configFile.Content() errors: the file was deleted/moved after discovery, permissions deny read, it's a directory not a file, or the underlying watch/reader returns an I/O error.
Common situations: Operator points --endpoint-config or --endpoint-config-ndjson at a missing or renamed file; k8s ConfigMap mount not yet present or removed; file unreadable by the Thanos process user (permissions/SELinux).
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- unable to load config file
- unable to load config initially
- unable to unmarshal config content
- endpoint
- unable to validate endpoints
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/3b359685186add95.
Report an issue: GitHub.
Appendix: source
Thrown at cmd/thanos/endpointset.go:175
if cfg.Compression != "none" && cfg.Compression != "snappy" {
return errors.Newf("invalid compression: %s, must be 'none' or 'snappy'", cfg.Compression)
}
return nil
}
func (er *endpointConfigProvider) config() EndpointConfig {
er.mu.Lock()
defer er.mu.Unlock()
res := EndpointConfig{Endpoints: make([]endpointSettings, len(er.cfg.Endpoints)), DefaultClientConfig: er.cfg.DefaultClientConfig}
copy(res.Endpoints, er.cfg.Endpoints)
return res
}
func (er *endpointConfigProvider) parse(configFile fileContent) (EndpointConfig, error) {
content, err := configFile.Content()
if err != nil {
return EndpointConfig{}, errors.Wrapf(err, "unable to load config content: %s", configFile.Path())
}
var cfg EndpointConfig
if err := yaml.Unmarshal(content, &cfg); err != nil {
return EndpointConfig{}, errors.Wrapf(err, "unable to unmarshal config content: %s", configFile.Path())
}
return cfg, nil
}
func (er *endpointConfigProvider) addStaticEndpoints(cfg *EndpointConfig) {
for _, e := range er.endpoints {
cfg.Endpoints = append(cfg.Endpoints, endpointSettings{
Address: e,
})
}
for _, e := range er.endpointGroups {
cfg.Endpoints = append(cfg.Endpoints, endpointSettings{
Address: e,
Group: true,View on GitHub (pinned to 35b8b99117)