tracel-ai/burn · error

Failed to create VGG19 cache file for Gram Matrix Loss

Error message

Failed to create VGG19 cache file for Gram Matrix Loss

What it means

`download_weights_if_not_saved` in crates/burn-vision/src/loss/gram_matrix/weights.rs:47 panics when `File::create` fails on the temporary file `cache_path.with_extension("pth.tmp")` used for an atomic VGG19 weights download. The library deliberately writes to a temp name first and renames it only after a complete write, so a panic here means the temp file could not even be created. The final cache file is untouched, so a retry is safe.

Source

Thrown at crates/burn-vision/src/loss/gram_matrix/weights.rs:47

}

/// Downloads the pretrained weights to the `cache_path` if they don't exist already.
///
/// Requires an active internet connection on the first run. Subsequent runs will
/// use the locally cached `.pth` file.
fn download_weights_if_not_saved(cache_path: &PathBuf) {
    if !cache_path.exists() {
        let bytes = download_file_as_bytes(
            VGG19_URL,
            "Downloading VGG19 ImageNet weights for Gram Matrix Loss...",
        );

        // Write to a temporary file. If writing gets completed, then rename to the actual/correct name.
        // If writing is not completed, the file with the correct name (i.e. `cache_path`) will not exist
        // so this code block can run again which is the desired behavior.
        let temp_path = cache_path.with_extension("pth.tmp");
        let mut file = File::create(&temp_path)
            .expect("Failed to create VGG19 cache file for Gram Matrix Loss");
        file.write_all(&bytes)
            .expect("Failed to write VGG19 weights to the cache file for Gram Matrix Loss");

        rename(temp_path, cache_path)
            .expect("Failed to rename temporary file to the actual VGG19 cache file name for Gram Matrix Loss");
    }
}

/// Loads ImageNet pretrained weights into the provided VGG19 feature extractor.
///
/// This function downloads the official PyTorch VGG19 weights, remaps the keys
/// from PyTorch's `features.X` format to Burn's `convX_Y` format, and loads
/// them into the module.
///
/// # Arguments
///
/// - `vgg19` - An initialized VGG19 module with random weights.
///

View on GitHub (pinned to d16f7ba2ed)

Solutions

  1. Delete stale temp files in the cache dir: `rm ~/.cache/burn-pretrained-models/loss/vgg19/*.pth.tmp` and retry
  2. Verify the vgg19 cache directory exists and is writable by the current user (`ls -ld`, `touch` test) and fix permissions
  3. Free disk space if `df` shows the cache filesystem is full
  4. Rerun single-threaded or per-user cache dirs to avoid concurrent downloaders clobbering each other

Example fix

// before: panic on temp-file creation
let temp_path = cache_path.with_extension("pth.tmp");
let mut file = File::create(&temp_path)
    .expect("Failed to create VGG19 cache file for Gram Matrix Loss");
// after: include the path in the error for diagnosis
let temp_path = cache_path.with_extension("pth.tmp");
let mut file = File::create(&temp_path).with_context(|| {
    format!("Failed to create temp file {} for VGG19 weights", temp_path.display())
})?;
Defensive patterns

Strategy: retry

Validate before calling

// Clean stale temp files and verify the dir is writable before downloading
let cache_dir = dirs::cache_dir().unwrap().join("burn-pretrained-models/loss/vgg19");
for entry in std::fs::read_dir(&cache_dir).into_iter().flatten().flatten() {
    let p = entry.path();
    if p.extension().map_or(false, |e| e == "tmp") {
        let _ = std::fs::remove_file(&p);
    }
}
assert!(OpenOptions::new().write(true).create(true)
    .open(cache_dir.join(".probe")).is_ok(), "vgg19 cache dir not writable");

Type guard

fn temp_files_stale(cache_dir: &std::path::Path) -> bool {
    std::fs::read_dir(cache_dir).map(|rd| rd.flatten()
        .any(|e| e.path().to_string_lossy().ends_with(".pth.tmp")))
        .unwrap_or(false)
}

Try / catch

for attempt in 1..=3 {
    match std::panic::catch_unwind(||
        burn_vision::loss::gram_matrix::load_vgg19_weights(device)
    ) {
        Ok(_) => break,
        Err(_) if attempt < 3 => {
            // remove stale .pth.tmp then back off and retry
            std::thread::sleep(std::time::Duration::from_secs(2u64.pow(attempt)));
        }
        Err(_) => eprintln!("VGG19 cache download failed after retries"),
    }
}

Prevention

When it happens

Trigger: Calling `load_vgg19_weights` with a missing cache file, where creating `<cache>.pth.tmp` fails: the cache directory does not exist or is not writable (e.g. it was removed between `get_cache_dir` and this point), a leftover `.pth.tmp` exists with no write permission, or the path component is a directory/file conflict.

Common situations: Two processes racing where one deleted or re-created the cache directory; a stale read-only `.pth.tmp` from a previous crashed run run under a different user; disk full so create fails with ENOSPC; temp name colliding with a directory named `weights.pth.tmp`.

Related errors


AI-assisted analysis of tracel-ai/burn@d16f7ba2ed (2026-09-05). Data as JSON: /api/errors/f6917d488ce3cccc. Report an issue: GitHub.