actix/actix-web · error · ProtocolError
unknown continuation fragment
Error message
unknown continuation fragment: {} What it means
ProtocolError::ContinuationFragment(OpCode) is raised in codec.rs:259 when an unfinished (FIN bit = 0) frame arrives with an opcode other than Continue/Text/Binary. RFC 6455 forbids fragmenting control frames (Close/Ping/Pong), so a non-final Close/Ping/Pong is logged as an unknown continuation fragment and rejected. It is distinct from ContinuationNotStarted/ContinuationStarted which track the fragmentation state machine.
Solutions
- Ensure control frames (Close/Ping/Pong) are always sent with FIN=1 and unfragmented.
- Use the actix Codec/Message API which never fragments control frames.
- Treat the error as fatal and close the connection (handled by the dispatcher).
Example fix
// before: control frame with FIN=0 (fragmented) - invalid // after: always set FIN=1 on Ping/Pong/Close via the standard message API frame.send(Message::Ping(payload)); // Codec sets FIN correctly
Defensive patterns
Strategy: try-catch
Try / catch
match decode_result {
Err(actix_http::ws::ProtocolError::ContinuationFragment(op)) => {
log::error!("fragmented control frame {op}");
// RFC violation; terminate the connection
return Err(CloseCode::Protocol.into());
}
_ => { /* ... */ }
} Prevention
- Always set FIN=1 on Close/Ping/Pong.
- Use the actix Codec which never fragments control frames.
- Treat this error as a connection-ending protocol violation.
When it happens
Trigger: A peer sends a Close, Ping, or Pong frame with the FIN bit cleared (an attempt to fragment a control frame). The codec's decode (codec.rs:257) hits the wildcard arm and returns this error.
Common situations: A non-conformant client that fragments ping/pong keep-alives; a custom WS implementation misunderstanding the fragmentation rules; stream corruption flipping the FIN bit.
Related errors
- invalid control frame length
- invalid opcode ( )
- Invalid opcode ( )
- Unknown continuation fragment
- Invalid chunk body CR
AI-assisted analysis of actix/actix-web@4d435abc28 (2026-08-09).
Data as JSON: /api/errors/ad26e9dee705e567.
Report an issue: GitHub.
Appendix: source
Thrown at actix-http/src/ws/mod.rs:63
/// Bad opcode.
#[display("bad opcode")]
BadOpCode,
/// A payload reached size limit.
#[display("payload reached size limit")]
Overflow,
/// Continuation has not started.
#[display("continuation has not started")]
ContinuationNotStarted,
/// Received new continuation but it is already started.
#[display("received new continuation but it has already started")]
ContinuationStarted,
/// Unknown continuation fragment.
#[display("unknown continuation fragment: {}", _0)]
ContinuationFragment(#[error(not(source))] OpCode),
/// I/O error.
#[display("I/O error: {}", _0)]
Io(io::Error),
}
/// WebSocket handshake errors
#[derive(Debug, Clone, Copy, PartialEq, Eq, Display, Error)]
pub enum HandshakeError {
/// Only get method is allowed.
#[display("method not allowed")]
GetMethodRequired,
/// Upgrade header if not set to WebSocket.
#[display("WebSocket upgrade is expected")]
NoWebsocketUpgrade,
/// Connection header is not set to upgrade.View on GitHub (pinned to 4d435abc28)