ramensoftware/windhawk · error · SettingsError
value is too large for the registry
Error message
value is too large for the registry
What it means
The value data length exceeds what the Win32 registry API's 32-bit length parameter can represent, so set_raw refuses the write rather than passing a clamped length that would not match the buffer. Registry values are practically far smaller, so this almost always signals a bug in the caller.
Solutions
- Check the payload size before writing and reject/truncate values above a sane limit.
- Store large data in a file and keep its path (or hash) in the registry value instead.
- Fix buffer-construction logic that inflates the data (duplicate appends, wrong multiplier).
Example fix
// before
let data = std::fs::read(&huge_file)?;
settings.set_binary("dump", &data)?; // > u32::MAX fails
// after
let data = std::fs::read(&huge_file)?;
if data.len() > 1_048_576 {
std::fs::write("dump.bin", &data)?;
settings.set_string("dump_path", "dump.bin")?;
} else {
settings.set_binary("dump", &data)?;
} Defensive patterns
Strategy: validation
Validate before calling
fn assert_payload_fits(data: &[u8]) -> Result<(), String> {
if data.len() > u32::MAX as usize { Err("payload too large for registry".into()) } else { Ok(()) }
} Type guard
fn fits_registry(d: &[u8]) -> bool { d.len() <= u32::MAX as usize } Try / catch
match settings.set_binary("blob", &data) {
Err(e) if e.message().contains("too large") => eprintln!("store large payload in a file instead"),
r => r?,
} Prevention
- Cap value sizes at a sane bound (e.g. 1 MiB) before writing.
- Store large blobs in files; keep only paths/hashes in the registry.
- Audit buffer-construction code for accidental duplication/size inflation.
- Add round-trip tests with realistic payload sizes.
When it happens
Trigger: Calling set_string/set_int/set_binary with a data buffer of 4 GiB or more (u32::try_from(data.len()) fails) — typically from passing a huge buffer or an arithmetic error computing the payload.
Common situations: Accidentally passing an entire multi-GB file as a value; a loop appending to a buffer unbounded; unit mix-up (bytes vs KiB) inflating the size.
Understand the failure class
Background: "File too large" / "file size exceeds limit" errors: why libraries cap file sizes and how to fix them — this error's family across 46 libraries.
Related errors
- value name contains a NUL
- RegQueryValueEx (size)
- RegQueryValueEx (data)
- RegSetValueEx
- value contains a NUL character
AI-assisted analysis of ramensoftware/windhawk@61d99ed8e1 (2026-09-12).
Data as JSON: /api/errors/2cfe92783c3a0e92.
Report an issue: GitHub.
Appendix: source
Thrown at src/windhawk-core/windows/src/registry.rs:459
return Ok(None);
}
if rc != ERROR_SUCCESS {
return Err(self.err("get", rc, "RegQueryValueEx (data)"));
}
buf.truncate(data_size as usize);
Ok(Some((value_type, buf)))
}
fn set_raw(&self, name: &str, value_type: u32, data: &[u8]) -> Result<(), SettingsError> {
self.check_name("set", name)?;
let Some(hkey) = self.hkey() else {
return Err(self.err("set", 0, "set on a read-only/absent key"));
};
let name_w = to_wide(name);
// A length the API's u32 cannot hold has no honest value to pass, and a
// clamped one would hand the call a length the buffer does not have.
let len = u32::try_from(data.len())
.map_err(|_| self.err("set", 0, "value is too large for the registry"))?;
// SAFETY: name_w is NUL-terminated; data/len describe a valid buffer.
let rc =
unsafe { RegSetValueExW(hkey, name_w.as_ptr(), 0, value_type, data.as_ptr(), len) };
if rc == ERROR_SUCCESS {
Ok(())
} else {
Err(self.err("set", rc, "RegSetValueEx"))
}
}
}
/// Decode a `REG_SZ` byte buffer (UTF-16LE, possibly NUL-terminated).
fn decode_sz(bytes: &[u8]) -> String {
let units: Vec<u16> = bytes
.chunks_exact(2)
.map(|c| u16::from_le_bytes([c[0], c[1]]))
.collect();
from_wide_nul(&units)View on GitHub (pinned to 61d99ed8e1)