{"record":{"id":"4161cf4a1d577ab3","repo":"sinelaw/fresh","slug":"ws-frame-too-large-len-bytes","errorCode":null,"errorMessage":"ws frame too large ({len} bytes)","messagePattern":"ws frame too large \\((.+?) bytes\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/fresh-editor/src/webui/mod.rs","lineNumber":1307,"sourceCode":"    let fin = buf[0] & 0x80 != 0;\n    let opcode = buf[0] & 0x0F;\n    let masked = buf[1] & 0x80 != 0;\n    let (mut len, mut off) = ((buf[1] & 0x7F) as u64, 2usize);\n    if len == 126 {\n        if buf.len() < 4 {\n            return Ok(None);\n        }\n        len = u16::from_be_bytes([buf[2], buf[3]]) as u64;\n        off = 4;\n    } else if len == 127 {\n        if buf.len() < 10 {\n            return Ok(None);\n        }\n        len = u64::from_be_bytes(buf[2..10].try_into().unwrap());\n        off = 10;\n    }\n    if len > WS_PAYLOAD_CAP as u64 {\n        anyhow::bail!(\"ws frame too large ({len} bytes)\");\n    }\n    let mask = if masked {\n        if buf.len() < off + 4 {\n            return Ok(None);\n        }\n        let k = [buf[off], buf[off + 1], buf[off + 2], buf[off + 3]];\n        off += 4;\n        Some(k)\n    } else {\n        None\n    };\n    let len = len as usize;\n    if buf.len() < off + len {\n        return Ok(None);\n    }\n    let mut payload = buf[off..off + len].to_vec();\n    if let Some(k) = mask {\n        // Client→server frames are always masked; unmask in place.","sourceCodeStart":1289,"sourceCodeEnd":1325,"githubUrl":"https://github.com/sinelaw/fresh/blob/67894ca5463dbd7a89bb31add4627c27d6b79d83/crates/fresh-editor/src/webui/mod.rs#L1289-L1325","documentation":"ws_parse_frame (invoked from drain_messages) parsed a WebSocket frame whose declared payload length exceeds WS_PAYLOAD_CAP. mod.rs:1307 bails to protect the editor's embedded web UI from oversized/malicious frames that could exhaust memory. The connection's frame is rejected outright.","triggerScenarios":"A WebSocket client sends a frame with a 64-bit extended length header whose value exceeds WS_PAYLOAD_CAP — either an attacker sending crafted frames, a buggy client, or corruption of the length prefix.","commonSituations":"Malicious requests against an exposed dev web-UI port; proxy/middleware mangling frame headers; a client library fragmenting or mis-framing messages.","solutions":["Fix the client to split large payloads into frames within the server's size cap","Raise WS_PAYLOAD_CAP if your application legitimately sends larger messages (and re-evaluate DoS exposure)","Inspect who is connecting to the WebSocket port — an unexpected oversized frame usually means a non-WebSocket or hostile client"],"exampleFix":"// client side: before\nws.send(hugeJsonString); // > cap, server bails\n// after\nfor chunk in split_into_frames(hugeJsonString, MAX_FRAME_SIZE) {\n    ws.send(chunk);\n}","handlingStrategy":"validation","validationCode":"if payload.len() > WS_PAYLOAD_CAP {\n    return Err(format!(\"payload {} exceeds server cap\", payload.len()));\n}","typeGuard":null,"tryCatchPattern":"ws.on('error', (e) => {\n  if (String(e).includes('ws frame too large')) { reconnectWithChunking(); }\n});","preventionTips":["Know the server's WS_PAYLOAD_CAP and chunk large messages client-side","Never expose the dev WebSocket port to untrusted networks","Validate message sizes at the application layer before sending over the socket"],"tags":["websocket","network","security","payload-limit"],"backgroundTag":"payload-too-large","analyzedSha":"67894ca5463dbd7a89bb31add4627c27d6b79d83","analyzedAt":"2026-09-13T15:04:03.701Z","contentChangedAt":"2026-09-13T15:04:03.701Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}