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

  1. Check the payload size before writing and reject/truncate values above a sane limit.
  2. Store large data in a file and keep its path (or hash) in the registry value instead.
  3. 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

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


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)