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
- Set the env var to an absolute path: API_KEY_FILE=/etc/glance/api_key.
- Replace ~ with the full home directory path (/home/user/...).
- 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
- Always use leading-slash absolute paths in *_FILE variables.
- Expand ~ manually; Go's filepath treats it as relative.
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
- URL is required
- nested groups are not supported
- split columns inside of groups are not supported
- source is required
- subreddit is required
AI-assisted analysis of glanceapp/glance@91324e8de7 (2026-08-15).
Data as JSON: /api/errors/7e10a6a3550a72f3.
Report an issue: GitHub.