{"id":"ea6580d267e3b020","repo":"rust-lang/cargo","slug":"unable-to-read-cargo-ok-file-at-path-e","errorCode":null,"errorMessage":"unable to read .cargo-ok file at {path:?}: {e}","messagePattern":"unable to read \\.cargo-ok file at (.+?): (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/sources/registry/mod.rs","lineNumber":585,"sourceCode":"                        .mark_registry_src_used(global_cache_tracker::RegistrySrc {\n                            encoded_registry_name: self.name,\n                            package_dir: package_dir.into(),\n                            size: None,\n                        });\n                    return Ok(unpack_dir.to_path_buf());\n                }\n                _ => {\n                    if ok == \"ok\" {\n                        tracing::debug!(\"old `ok` content found, clearing cache\");\n                    } else {\n                        tracing::warn!(\"unrecognized .cargo-ok content, clearing cache: {ok}\");\n                    }\n                    // See comment of `unpack_package` about why removing all stuff.\n                    paths::remove_dir_all(dst.as_path_unlocked())?;\n                }\n            },\n            Err(e) if e.kind() == io::ErrorKind::NotFound => {}\n            Err(e) => anyhow::bail!(\"unable to read .cargo-ok file at {path:?}: {e}\"),\n        }\n        dst.create_dir()?;\n\n        let bytes_written = unpack(self.gctx, tarball, unpack_dir, &|_| true)?;\n        update_mtime_for_generated_files(unpack_dir);\n\n        // Now that we've finished unpacking, create and write to the lock file to indicate that\n        // unpacking was successful.\n        let mut ok = OpenOptions::new()\n            .create_new(true)\n            .read(true)\n            .write(true)\n            .open(&path)\n            .with_context(|| format!(\"failed to open `{}`\", path.display()))?;\n\n        let lock_meta = LockMetadata { v: 1 };\n        write!(ok, \"{}\", serde_json::to_string(&lock_meta).unwrap())?;\n","sourceCodeStart":567,"sourceCodeEnd":603,"githubUrl":"https://github.com/rust-lang/cargo/blob/0e07a155371a6ce88ae53a2c00df940280c09a67/src/sources/registry/mod.rs#L567-L603","documentation":"Before unpacking a `.crate`, Cargo reads its `.cargo-ok` marker file (src/sources/registry/mod.rs:562). A `NotFound` IO error is expected and ignored (meaning 'unpack fresh'), but any *other* IO error (permission denied, disk error, broken symlink) is fatal and reported with this message including `{path:?}` and the underlying `{e}`. This protects against silently treating an unreadable cache as 'not yet unpacked'.","triggerScenarios":"The `.cargo-ok` file exists but can't be read due to permissions (`EACCES`), a broken symlink, a filesystem I/O error, or a race where the file/dir was removed mid-operation with a non-NotFound error.","commonSituations":"`chmod`/ownership changes under `~/.cargo/registry/src/`; a broken symlink left by a failed sync; disk/filesystem corruption; SELinux/AppArmor denying reads; running as a different user than the one that created the cache.","solutions":["Inspect the exact `{path}` from the message and check permissions/ownership: `ls -la <dir>`.","Fix ownership/permissions (`chown`/`chmod`) or remove the corrupted unpacked package directory so Cargo re-unpacks.","If the disk/filesystem is failing, run `fsck` / move `CARGO_HOME` to healthy storage."],"exampleFix":"# before: .cargo-ok unreadable (wrong owner)\nsudo chown -R $USER:$USER ~/.cargo\n# or just evict the bad unpack\ncargo cache --autoclean  # / rm -rf ~/.cargo/registry/src/<reg>/<pkg>-<ver>","handlingStrategy":"validation","validationCode":"// If you manipulate ~/.cargo programmatically, ensure .cargo-ok is readable.\nfn cargo_ok_readable(p: &Path) -> bool {\n    match std::fs::read_to_string(p) {\n        Ok(_) => true,\n        Err(e) if e.kind() == std::io::ErrorKind::NotFound => true, // expected\n        Err(_) => false,\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Run cargo as a single user; avoid `sudo`/ownership flips under `~/.cargo`.","Don't symlink `.cargo-ok` to unreadable targets.","Periodically clear corrupted unpack dirs with `cargo cache --autoclean`."],"tags":["cargo","registry","filesystem","permissions","io"],"analyzedSha":"0e07a155371a6ce88ae53a2c00df940280c09a67","analyzedAt":"2026-08-06T01:46:58.334Z","schemaVersion":2}