ramensoftware/windhawk · error · SettingsError
RegQueryValueEx (data)
Error message
RegQueryValueEx (data)
What it means
The second (sized) RegQueryValueExW call inside query_raw failed with an OS error other than ERROR_SUCCESS. The size query succeeded but reading the actual data buffer failed; the error carries the Win32 function name and the OS error code.
Solutions
- Retry query_raw once; a transient size race typically resolves on the second read.
- Check the wrapped OS code (ERROR_MORE_DATA implies the value grew — retry with a larger buffer).
- Ensure the key handle is still valid and opened with KEY_QUERY_VALUE access.
- Serialize writes/reads (avoid concurrent writers to the same value) if a race is suspected.
Example fix
// before
let (t, data) = settings.query_raw(name)?; // can fail transiently
// after
let mut tries = 0;
let (t, data) = loop {
match settings.query_raw(name) {
Ok(v) => break v,
Err(e) if tries < 2 => { tries += 1; continue; }
Err(e) => return Err(e),
}
}; Defensive patterns
Strategy: retry
Validate before calling
// no pre-call validation; failure is environmental or a size race
Try / catch
let mut tries = 0;
let val = loop {
match settings.get_string("x") {
Ok(v) => break v,
Err(e) if tries < 2 && e.message().contains("RegQueryValueEx") => { tries += 1; continue; }
Err(e) => return Err(e),
}
}; Prevention
- Avoid concurrent writers to the same registry value.
- Retry transient read failures with a short backoff.
- Re-open the key if reads fail repeatedly (stale handle).
- Keep values small so the size-probe/read pair is atomic in practice.
When it happens
Trigger: Reading a value whose size changed or grew between the size probe and the data read (a race with another writer), an access-denied on the data read, or a handle invalidated mid-read.
Common situations: Another process concurrently rewriting the value; very large values where the size probe and read race; transient registry access issues under restrictive policies.
Related errors
- RegQueryValueEx (size)
- value name contains a NUL
- value is too large for the registry
- RegSetValueEx
- RegDeleteValue
AI-assisted analysis of ramensoftware/windhawk@61d99ed8e1 (2026-09-12).
Data as JSON: /api/errors/99f6886e4593d97a.
Report an issue: GitHub.
Appendix: source
Thrown at src/windhawk-core/windows/src/registry.rs:444
}
let mut buf = vec![0u8; size as usize];
let mut data_size = size;
// SAFETY: buf has data_size bytes; out params valid.
let rc = unsafe {
RegQueryValueExW(
hkey,
name_w.as_ptr(),
std::ptr::null(),
&mut value_type,
buf.as_mut_ptr(),
&mut data_size,
)
};
if rc == ERROR_FILE_NOT_FOUND {
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) };View on GitHub (pinned to 61d99ed8e1)