{"record":{"id":"30027b0d1c1dd7e6","repo":"actix/actix-web","slug":"unknown-continuation-fragment-30027b","errorCode":null,"errorMessage":"Unknown continuation fragment: {}","messagePattern":"Unknown continuation fragment: (.+?)","errorType":"validation","errorClass":"ProtocolError","httpStatus":null,"severity":"error","filePath":"actix-http/src/ws/mod.rs","lineNumber":78,"sourceCode":"    /// Bad opcode.\n    #[display(\"Bad opcode\")]\n    BadOpCode,\n\n    /// A payload reached size limit.\n    #[display(\"Payload reached size limit\")]\n    Overflow,\n\n    /// Continuation has not started.\n    #[display(\"Continuation has not started\")]\n    ContinuationNotStarted,\n\n    /// Received new continuation but it is already started.\n    #[display(\"Received new continuation but it has already started\")]\n    ContinuationStarted,\n\n    /// Unknown continuation fragment.\n    #[display(\"Unknown continuation fragment: {}\", _0)]\n    ContinuationFragment(#[error(not(source))] OpCode),\n\n    /// I/O error.\n    #[display(\"I/O error: {}\", _0)]\n    Io(io::Error),\n}\n\n/// WebSocket handshake errors\n#[derive(Debug, Clone, Copy, PartialEq, Eq, Display, Error)]\npub enum HandshakeError {\n    /// Only get method is allowed.\n    #[display(\"method not allowed\")]\n    GetMethodRequired,\n\n    /// Upgrade header if not set to WebSocket.\n    #[display(\"WebSocket upgrade is expected\")]\n    NoWebsocketUpgrade,\n\n    /// Connection header is not set to upgrade.","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/actix/actix-web/blob/c215607f4b6e9ba9accff4a949a33c98f218db20/actix-http/src/ws/mod.rs#L60-L96","documentation":"This is `ws::ProtocolError::ContinuationFragment(OpCode)` from actix-http's WebSocket handling. A fragmented message must consist of a first frame (text/binary) followed only by continuation frames (opcode 0x0). This error is raised when a continuation frame arrives when no fragmented message is in progress, i.e. the fragment sequence state machine is out of sync.","triggerScenarios":"The ws message assembler receives a continuation frame (opcode 0x0) while `continuation` state is None/finished — e.g. a lone continuation frame or a continuation after the FIN frame already closed the message.","commonSituations":"A peer that emits continuation frames without a preceding fragmented text/binary frame, double-sending the final fragment, a proxy reordering/dropping frames, or resuming a session mid-message after reconnecting.","solutions":["Fix the sending side so every fragmented message starts with an initial text/binary frame (FIN=0) before any continuation frames.","Ensure only the last fragment has FIN=1 and that no extra continuation frames are sent after it.","Check for intermediaries (proxies/load balancers) that could reorder or duplicate WebSocket frames and bypass or replace them.","On error, reset the per-connection message state and close with CloseCode::Protocol; do not attempt to salvage the partial message."],"exampleFix":"// before: sender starts fragments with opcode 0x0\nsend_frame(Frame::continuation(payload).fin(false));\n// after: first fragment must carry the message type\nsend_frame(Frame::text(payload).fin(false));\nsend_frame(Frame::continuation(rest).fin(true));","handlingStrategy":"try-catch","validationCode":"// sender-side check before emitting a continuation frame\nif (!fragmentationActive) throw new Error(\"continuation frame without an open fragmented message\");","typeGuard":"struct FragmentState { in_progress: bool }\nfn can_send_continuation(state: &FragmentState) -> bool {\n    state.in_progress\n}","tryCatchPattern":"match result {\n    Err(ProtocolError::ContinuationFragment(op)) => {\n        log::warn!(\"unexpected continuation fragment (op {:?}); resetting message state\", op);\n        reset_assembler();\n        close_with(CloseCode::Protocol);\n    }\n    other => handle(other),\n}","preventionTips":["Always start a fragmented message with a text/binary frame (FIN=0), never a continuation frame","Set FIN=1 exactly once, on the final fragment","Reset fragment state on reconnect; never resume mid-message after a dropped connection","Test fragmented sends through any proxies to ensure frame order is preserved"],"tags":["websocket","protocol","fragmentation","state-machine"],"backgroundTag":"invalid-state-transition","analyzedSha":"c215607f4b6e9ba9accff4a949a33c98f218db20","analyzedAt":"2026-09-09T15:57:34.010Z","contentChangedAt":"2026-09-09T15:57:34.010Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}