{"record":{"id":"2cfe92783c3a0e92","repo":"ramensoftware/windhawk","slug":"value-is-too-large-for-the-registry","errorCode":null,"errorMessage":"value is too large for the registry","messagePattern":"value is too large for the registry","errorType":"validation","errorClass":"SettingsError","httpStatus":null,"severity":"error","filePath":"src/windhawk-core/windows/src/registry.rs","lineNumber":459,"sourceCode":"            return Ok(None);\n        }\n        if rc != ERROR_SUCCESS {\n            return Err(self.err(\"get\", rc, \"RegQueryValueEx (data)\"));\n        }\n        buf.truncate(data_size as usize);\n        Ok(Some((value_type, buf)))\n    }\n\n    fn set_raw(&self, name: &str, value_type: u32, data: &[u8]) -> Result<(), SettingsError> {\n        self.check_name(\"set\", name)?;\n        let Some(hkey) = self.hkey() else {\n            return Err(self.err(\"set\", 0, \"set on a read-only/absent key\"));\n        };\n        let name_w = to_wide(name);\n        // A length the API's u32 cannot hold has no honest value to pass, and a\n        // clamped one would hand the call a length the buffer does not have.\n        let len = u32::try_from(data.len())\n            .map_err(|_| self.err(\"set\", 0, \"value is too large for the registry\"))?;\n        // SAFETY: name_w is NUL-terminated; data/len describe a valid buffer.\n        let rc =\n            unsafe { RegSetValueExW(hkey, name_w.as_ptr(), 0, value_type, data.as_ptr(), len) };\n        if rc == ERROR_SUCCESS {\n            Ok(())\n        } else {\n            Err(self.err(\"set\", rc, \"RegSetValueEx\"))\n        }\n    }\n}\n\n/// Decode a `REG_SZ` byte buffer (UTF-16LE, possibly NUL-terminated).\nfn decode_sz(bytes: &[u8]) -> String {\n    let units: Vec<u16> = bytes\n        .chunks_exact(2)\n        .map(|c| u16::from_le_bytes([c[0], c[1]]))\n        .collect();\n    from_wide_nul(&units)","sourceCodeStart":441,"sourceCodeEnd":477,"githubUrl":"https://github.com/ramensoftware/windhawk/blob/61d99ed8e182e1af1b60109612b6763ad1b4b74e/src/windhawk-core/windows/src/registry.rs#L441-L477","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)."],"exampleFix":"// before\nlet data = std::fs::read(&huge_file)?;\nsettings.set_binary(\"dump\", &data)?; // > u32::MAX fails\n// after\nlet data = std::fs::read(&huge_file)?;\nif data.len() > 1_048_576 {\n    std::fs::write(\"dump.bin\", &data)?;\n    settings.set_string(\"dump_path\", \"dump.bin\")?;\n} else {\n    settings.set_binary(\"dump\", &data)?;\n}","handlingStrategy":"validation","validationCode":"fn assert_payload_fits(data: &[u8]) -> Result<(), String> {\n    if data.len() > u32::MAX as usize { Err(\"payload too large for registry\".into()) } else { Ok(()) }\n}","typeGuard":"fn fits_registry(d: &[u8]) -> bool { d.len() <= u32::MAX as usize }","tryCatchPattern":"match settings.set_binary(\"blob\", &data) {\n    Err(e) if e.message().contains(\"too large\") => eprintln!(\"store large payload in a file instead\"),\n    r => r?,\n}","preventionTips":["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."],"tags":["registry","size-limit","win32","validation"],"backgroundTag":"file-size-limit-exceeded","analyzedSha":"61d99ed8e182e1af1b60109612b6763ad1b4b74e","analyzedAt":"2026-09-12T14:02:41.115Z","contentChangedAt":"2026-09-12T14:02:41.115Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}