tonhowtf/omniget · error · anyhow::Error
No valid cookies found in file (expected Netscape format)
Error message
No valid cookies found in file (expected Netscape format)
What it means
import_cookies_file validates a user-supplied cookie file by running it through parse_netscape_cookies before installing it into the cookies directory. The parser only accepts Netscape cookie-file lines with at least 7 tab-separated fields (domain, flag, path, secure, expiration, name, value) and non-empty name/value. If nothing in the file parses, import_cookies_file aborts with this error instead of copying a cookie file that yt-dlp would later reject or silently ignore.
Solutions
- Export the cookies in Netscape format (e.g. a browser 'Get cookies.txt' extension, or `yt-dlp --cookies-from-browser <browser>` style export) and re-run import_cookies_file with that file.
- Verify the file's lines have 7 tab-separated fields: domain\tflag\tpath\tsecure\texpiration\tname\tvalue; re-export or convert with a JSON-to-Netscape converter if separators are spaces or it is JSON.
- Check the file is non-empty and contains actual cookie data (no leading #HttpOnly_ comments-only file, no truncated export) before importing.
- If the file is fine but spaces-separated, convert separators to tabs (sed/awk) and retry.
Example fix
// before: importing a JSON export
let raw = std::fs::read_to_string("cookies.json").unwrap();
import_cookies_file("cookies.json").unwrap(); // bail: No valid cookies found
// after: convert JSON to Netscape format first (name\tvalue lines with 7 tab fields), then import
// cookies.txt:
// .example.com TRUE / TRUE 1735689600 SESSION abc123
import_cookies_file("cookies.txt").unwrap(); Defensive patterns
Strategy: validation
Validate before calling
fn is_netscape_cookie_file(path: &str) -> bool {
let content = std::fs::read_to_string(path).unwrap_or_default();
content.lines().any(|l| {
let l = l.trim();
!l.is_empty() && !l.starts_with('#') && l.split('\t').count() >= 7
})
}
if !is_netscape_cookie_file("cookies.txt") {
eprintln!("not a Netscape cookies.txt file");
} Type guard
fn is_netscape_line(line: &str) -> bool {
let f: Vec<&str> = line.trim().split('\t').collect();
f.len() >= 7 && !f[5].is_empty() && !f[6].is_empty()
} Prevention
- Always export cookies with a 'cookies.txt' (Netscape) browser extension, never the JSON export.
- Open the file before importing and confirm lines have 7 tab-separated fields.
- Check the file is non-empty and not an HTML page accidentally saved as .txt.
- Keep cookie exports fresh; expired cookies still parse but will fail later at the HTTP layer.
When it happens
Trigger: Calling import_cookies_file with a file whose contents yield zero parsed cookies: (1) a JSON cookie export (e.g. from browser extensions) rather than Netscape format; (2) a Netscape file where fields are separated by spaces instead of tabs (fields.len() < 7); (3) a file containing only comments (# lines), blank lines, or an HTTP Set-Cookie header dump; (4) an empty or binary (e.g. SQLite) file passed by mistake.
Common situations: Users export cookies from a browser extension in JSON format and pass that file; users hand-copy cookie text with spaces instead of tabs; users pass an HTML login page saved to disk or a curl cookie jar in a different dialect; the file was created empty because the export failed upstream.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- Target domain is required for Cookie header import.
- Expected a JSON array of cookie objects.
- invalid domain: {domain}
- invalid JSON: {e}
- Extension playlist is {} bytes, over the {} byte limit
AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12).
Data as JSON: /api/errors/32805d47007f5fd8.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/omniget-cli/src/cookies.rs:92
let content = std::fs::read_to_string(src_path)
.with_context(|| format!("Failed to read {}", src_path.display()))?;
let cookies_dir = app_data_dir()
.ok_or_else(|| anyhow::anyhow!("Cannot determine app data directory"))?
.join(COOKIES_DIR);
std::fs::create_dir_all(&cookies_dir)?;
let dest_file = if let Some(n) = name {
cookies_dir.join(format!("cookies_{}.txt", n))
} else {
cookies_dir.join(DEFAULT_COOKIE_FILE)
};
// Parse to validate and count
let parsed = parse_netscape_cookies(&content);
if parsed.is_empty() {
anyhow::bail!("No valid cookies found in file (expected Netscape format)");
}
// Copy the raw file (preserving original format for yt-dlp consumption)
// Normalize line endings but otherwise keep as-is
let normalized = content.replace("\r\n", "\n").replace('\r', "\n");
std::fs::write(&dest_file, normalized)
.with_context(|| format!("Failed to write {}", dest_file.display()))?;
Ok(parsed.iter().map(|(_, s)| s.split(';').count()).sum())
}
/// List showing what the cookie file would look like when consumed
pub fn preview_import(src_path: &PathBuf) -> Result<Vec<(String, usize)>> {
let content = std::fs::read_to_string(src_path)
.with_context(|| format!("Failed to read {}", src_path.display()))?;
let parsed = parse_netscape_cookies(&content);
Ok(parsedView on GitHub (pinned to 8600b91f42)