thanos-io/thanos · error

getting absolute file path

Error message

getting absolute file path

What it means

PathContentReloader resolves the watched file's relative path to an absolute one with filepath.Abs before setting up the polling engine. If filepath.Abs fails (it only errors when the process cannot determine its working directory), this wrapped error is returned. It is essentially a filesystem/process-environment failure at startup of the config reloader.

Solutions

  1. Restart the process from a valid, existing working directory.
  2. Pass an absolute path to the file content so filepath.Abs does not need getwd.
  3. Check that the container/pod's WORKDIR exists and is not deleted at runtime.

Example fix

// before
reloader, err := extkingpin.PathContentReloader(ctx, content, logger, reload, d) // cwd deleted
// after
abs, _ := filepath.Abs(cfgPath) // resolve while cwd is valid, then
content := filestore.NewFileContent(abs)
reloader, err := extkingpin.PathContentReloader(ctx, content, logger, reload, d)
Defensive patterns

Strategy: fallback

Validate before calling

if _, err := os.Getwd(); err != nil { return fmt.Errorf("working directory unavailable: %w", err) }

Try / catch

if err := startConfigReloader(); err != nil { log.Error(err, "falling back to static config, no reload") }

Prevention

When it happens

Trigger: Calling PathContentReloader (directly or via StartConfigReloader/newEndpointConfigProvider) with a fileContent whose Path() plus a deleted or unreadable current working directory causes filepath.Abs(workingDir, path) to fail (getwd error).

Common situations: Starting Thanos from a working directory that was deleted while the process launched (common with containers swapping filesystems), or running with a corrupted cwd.

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


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

Appendix: source

Thrown at pkg/extkingpin/path_content_reloader.go:47

func (n NopConfigContent) Content() ([]byte, error) {
	return nil, nil
}

// Path returns an empty path.
func (n NopConfigContent) Path() string {
	return ""
}

// NewNopConfig creates a no-op config content (no configuration).
func NewNopConfig() NopConfigContent {
	return NopConfigContent{}
}

// PathContentReloader runs the reloadFunc when it detects that the contents of fileContent have changed.
func PathContentReloader(ctx context.Context, fileContent fileContent, logger log.Logger, reloadFunc func(), debounceTime time.Duration) error {
	filePath, err := filepath.Abs(fileContent.Path())
	if err != nil {
		return errors.Wrap(err, "getting absolute file path")
	}

	engine := &pollingEngine{
		filePath:   filePath,
		logger:     logger,
		debounce:   debounceTime,
		reloadFunc: reloadFunc,
	}
	return engine.start(ctx)
}

// pollingEngine keeps rereading the contents at filePath and when its checksum changes it runs the reloadFunc.
type pollingEngine struct {
	filePath         string
	logger           log.Logger
	debounce         time.Duration
	reloadFunc       func()
	previousChecksum [sha256.Size]byte

View on GitHub (pinned to 35b8b99117)