getzola/zola · error
{:?} is not inside the base site directory {:?}
Error message
{:?} is not inside the base site directory {:?} What it means
The `search_for_file` template helper resolves a user-supplied path against the site base path. If the resulting file exists but is not contained within the base site directory (checked via `is_path_in_directory`), it bails to prevent reading files outside the site — a path-traversal guard.
Source
Thrown at components/templates/src/helpers.rs:40
theme: &Option<String>,
output_path: &Path,
) -> Result<Option<(PathBuf, String)>> {
let mut search_paths =
vec![base_path.join("static"), base_path.join("content"), base_path.join(output_path)];
if let Some(t) = theme {
search_paths.push(base_path.join("themes").join(t).join("static"));
}
let actual_path = if path.starts_with("@/") {
Cow::Owned(path.replace("@/", "content/"))
} else {
Cow::Borrowed(path.trim_start_matches('/'))
};
let mut file_path = base_path.join(&*actual_path);
let mut file_exists = file_path.exists();
if file_exists && !is_path_in_directory(base_path, &file_path)? {
bail!("{:?} is not inside the base site directory {:?}", path, base_path);
}
if !file_exists {
// we need to search in all search folders now
for dir in &search_paths {
let p = dir.join(&*actual_path);
if p.exists() {
file_path = p;
file_exists = true;
break;
}
}
}
if file_exists { Ok(Some((file_path, actual_path.into_owned()))) } else { Ok(None) }
}
View on GitHub (pinned to 61d3082821)
Solutions
- Use a path relative to the site root without `..` segments
- Move the needed file inside the site directory (e.g. into `static/` or `content/`)
- Remove or re-point symlinks that escape the base directory
Example fix
// before
{{ get_file(path="../../shared/config.json") }}
// after
{{ get_file(path="static/config.json") }} Defensive patterns
Strategy: validation
Validate before calling
fn safe_relative(path: &str) -> bool {
let p = std::path::Path::new(path);
!p.is_absolute() && p.components().all(|c| !matches!(c, std::path::Component::ParentDir))
} Try / catch
match search_for_file(base_path, path, &search_paths) {
Ok(f) => read(f),
Err(e) if e.to_string().contains("not inside the base site directory") => {
eprintln!("path escapes site root, refusing: {path}");
}
Err(e) => return Err(e),
} Prevention
- Never use ../ or absolute paths in template file helpers
- Keep referenced assets inside the site directory
- Audit symlinks in the project that point outside the site root
When it happens
Trigger: Calling the template helper (`call`/`from_args`) with a path containing `..` segments or an absolute path that, after `base_path.join`, escapes the site directory (e.g. `../secrets.txt` or `/etc/passwd`).
Common situations: Template code using `{{ get_file(path="../../outside.txt") }}`; symlinks inside the site pointing outside the project; mistakenly passing absolute paths.
Related errors
- Either a `templates/` folder or a theme is required
- no templates registered
- could not parse domain `{}` from link
- could not parse domain `{}` from link: `{}`
- Failed to convert bytes to string : {}
AI-assisted analysis of getzola/zola@61d3082821 (2026-09-03).
Data as JSON: /api/errors/aa016f19ef84864e.
Report an issue: GitHub.