glanceapp/glance · error

readFileFromEnv: file path %s is not absolute

Error message

readFileFromEnv: file path %s is not absolute

What it means

Thrown by parseConfigVariableOfType for {{ file-from-env.NAME }} when the env var NAME exists but its value is not an absolute path (does not start with /). This is an explicit security guard: relative paths would resolve against Glance's working directory, making file reads dependent on where the process happens to run.

Source

Thrown at internal/glance/config.go:222

		secretPath := filepath.Join("/run/secrets", variableName)
		secret, err := os.ReadFile(secretPath)
		if err != nil {
			return "", false, fmt.Errorf("reading secret file: %v", err)
		}

		return strings.TrimSpace(string(secret)), false, nil
	case configVarTypeFileFromEnv:
		if !envVariableNamePattern.MatchString(variableName) {
			return "", true, nil
		}

		filePath, found := os.LookupEnv(variableName)
		if !found {
			return "", false, fmt.Errorf("readFileFromEnv: environment variable %s not found", variableName)
		}

		if !filepath.IsAbs(filePath) {
			return "", false, fmt.Errorf("readFileFromEnv: file path %s is not absolute", filePath)
		}

		fileContents, err := os.ReadFile(filePath)
		if err != nil {
			return "", false, fmt.Errorf("readFileFromEnv: reading file from %s: %v", variableName, err)
		}

		return strings.TrimSpace(string(fileContents)), false, nil
	default:
		return "", true, nil
	}
}

func formatWidgetInitError(err error, w widget) error {
	return fmt.Errorf("%s widget: %v", w.GetType(), err)
}

var configIncludePattern = regexp.MustCompile(`(?m)^([ \t]*)(?:-[ \t]*)?(?:!|\$)include:[ \t]*(.+)$`)

View on GitHub (pinned to 91324e8de7)

Solutions

  1. Set the env var to an absolute path: API_KEY_FILE=/etc/glance/api_key.
  2. Replace ~ with the full home directory path (/home/user/...).
  3. Check for leading/trailing whitespace or quotes around the value in compose/systemd definitions.

Example fix

# before
$ export API_KEY_FILE=secrets/api_key

# after
$ export API_KEY_FILE=/etc/glance/secrets/api_key
Defensive patterns

Strategy: validation

Validate before calling

for var in $(grep -oE '\{\{ *file-from-env\.[A-Za-z_][A-Za-z0-9_]* *\}\}' glance.yml | sed -E 's/.*file-from-env\.([A-Za-z0-9_]+).*/\1/'); do
  p=$(printenv "$var") || { echo "not set: $var"; exit 1; }
  case "$p" in /*) ;; *) echo "$var must be absolute, got: $p"; exit 1;; esac
done

Prevention

When it happens

Trigger: API_KEY_FILE=keys/api.key (relative), API_KEY_FILE=./token, or a value with leading whitespace/tilde like ~/secret — filepath.IsAbs returns false and the error fires.

Common situations: Setting the *_FILE variable with a relative path in a compose file or shell; using ~ shorthand which Go's filepath treats as relative; values quoted with accidental leading spaces.

Related errors


AI-assisted analysis of glanceapp/glance@91324e8de7 (2026-08-15). Data as JSON: /api/errors/7e10a6a3550a72f3. Report an issue: GitHub.