pola-rs/polars · critical
failed to open/create global file cache lockfile
Error message
failed to open/create global file cache lockfile: {err} What it means
The global file cache lockfile cannot be opened or created at the lock path, and the library panics instead of proceeding without the lock. The lockfile coordinates the background eviction manager. Failure almost always indicates filesystem permission or path issues.
Solutions
- Verify the cache directory and its parent are writable by the current user
- Point POLARS_TEMP_DIR to a writable location
- Check for sandbox/seccomp/SELinux rules blocking file creation in the temp dir
- Ensure a stale root-owned lockfile isn't blocking creation (fix ownership or remove it)
Example fix
// before POLARS_TEMP_DIR=/var/lock (root-owned) // after POLARS_TEMP_DIR=/home/user/.cache/polars
Defensive patterns
Strategy: validation
Validate before calling
use std::fs;
let base = std::env::var("POLARS_TEMP_DIR").unwrap_or_else(|_| std::env::temp_dir().display().to_string());
let lock_probe = format!("{base}/.polars-lock-probe");
match fs::OpenOptions::new().write(true).create(true).truncate(false).open(&lock_probe) {
Ok(_) => { let _ = fs::remove_file(&lock_probe); }
Err(e) => panic!("cannot create lockfiles in {base}: {e}"),
} Prevention
- Verify temp dir allows file creation (not just listing) at startup
- Check sandbox/SELinux policies permit writes there
- Clean up stale root-owned lockfiles after privileged runs
When it happens
Trigger: First initialization of the file cache lock: OpenOptions write+create on the lockfile path fails (EACCES, EROFS, ENOENT parent, etc.).
Common situations: Read-only temp directories, restrictive sandbox/SELinux policies, or a directory path owned by another user in multi-user environments.
Understand the failure class
Background: "open() failed", "failed to open file", "cannot create file" — what a file open error means and how to fix it — this error's family across 42 libraries.
Related errors
- failed to create file cache data directory: path =
- failed to create file cache directory: path =
- failed to create file cache metadata directory: path =
- failed to create spill directory
- finish_open: could not acquire shared lock on data file at
AI-assisted analysis of pola-rs/polars@fe841f959e (2026-09-18).
Data as JSON: /api/errors/d62bb3ee83462cf5.
Report an issue: GitHub.
Appendix: source
Thrown at crates/polars-io/src/file_cache/cache_lock.rs:20
use std::sync::{Arc, LazyLock};
use std::time::Duration;
use fs4::FileExt;
use parking_lot::{RwLock, RwLockReadGuard, RwLockWriteGuard};
use polars_core::runtime::ASYNC;
use super::utils::FILE_CACHE_PREFIX;
pub(super) static GLOBAL_FILE_CACHE_LOCK: LazyLock<GlobalLock> = LazyLock::new(|| {
let path = FILE_CACHE_PREFIX.join(".process-lock");
let file = std::fs::OpenOptions::new()
.write(true)
.create(true)
.truncate(false)
.open(path)
.map_err(|err| {
panic!("failed to open/create global file cache lockfile: {err}");
})
.unwrap();
let at_bool = Arc::new(AtomicBool::new(false));
// Holding this access tracker prevents the background task from
// unlocking the lock.
let access_tracker = AccessTracker(at_bool.clone());
let notify_lock_acquired = Arc::new(tokio::sync::Notify::new());
let notify_lock_acquired_2 = notify_lock_acquired.clone();
ASYNC.spawn(async move {
let at_bool = std::mem::ManuallyDrop::new(at_bool);
let access_tracker = at_bool.as_ref();
let notify_lock_acquired = notify_lock_acquired_2;
let verbose = false;
loop {
if verbose {View on GitHub (pinned to fe841f959e)