actix/actix-web · error · ProtocolError
invalid opcode ({})
Error message
invalid opcode ({}) What it means
ProtocolError::InvalidOpcode(u8) (ws/mod.rs:39) is thrown by Parser::parse_metadata in frame.rs:43-45 when the low 4 bits of the first WebSocket frame byte do not map to a defined OpCode (0,1,2,8,9,10) — i.e. values 3-7 or 11-15, which RFC 6455 §11.8 reserves. It indicates a peer that is sending non-conformant frames and the connection must be torn down with a protocol error.
Source
Thrown at actix-http/src/ws/mod.rs:38
codec::{Codec, Frame, Item, Message},
dispatcher::Dispatcher,
frame::Parser,
proto::{hash_key, CloseCode, CloseReason, OpCode},
};
/// WebSocket protocol errors.
#[derive(Debug, Display, Error, From)]
pub enum ProtocolError {
/// Received an unmasked frame from client.
#[display("received an unmasked frame from client")]
UnmaskedFrame,
/// Received a masked frame from server.
#[display("received a masked frame from server")]
MaskedFrame,
/// Encountered invalid opcode.
#[display("invalid opcode ({})", _0)]
InvalidOpcode(#[error(not(source))] u8),
/// Invalid control frame length
#[display("invalid control frame length ({})", _0)]
InvalidLength(#[error(not(source))] usize),
/// 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,
View on GitHub (pinned to 937960ca67)
Solutions
- Close the connection on this error; the peer is violating RFC 6455 and cannot be recovered mid-stream.
- Identify the peer client library/version and replace or patch it.
- If behind a reverse proxy, verify it is not corrupting WebSocket frames (disable buffering/HTTP/1.1 transformations on the Upgrade path).
- Add connection-level logging of the raw first byte to confirm the opcode value.
Defensive patterns
Strategy: try-catch
Try / catch
// In a WebSocket actor, handle the protocol error and close the connection.
match ws::Dispatcher::new(framed,Codec::new()).... {
Err(ProtocolError::InvalidOpcode(b)) => {
log::warn!("invalid ws opcode {b:#x}; closing");
// drop the actor / close the connection
}
Err(other) => { /* other protocol errors */ }
Ok(_) => {}
} Prevention
- Use a compliant WebSocket client library rather than hand-rolling frames.
- Do not attempt recovery from protocol errors; close and reconnect.
- Ensure reverse proxies pass WebSocket frames through unmodified.
When it happens
Trigger: A WebSocket peer (client or server) sends a frame whose opcode is reserved, e.g. opcode 3, 5, 7, 11, or 13. Observed with buggy or hand-rolled WS implementations, fuzzers, or intermediaries that corrupt the frame header.
Common situations: Interoperability with a non-compliant client library, corrupted frames from a misbehaving proxy, or active security fuzzing of the WS endpoint.
Related errors
- invalid control frame length ({})
- unknown continuation fragment: {}
- Invalid chunk size line: Invalid Size
- Invalid chunk size linear white space
- Invalid chunk size LF
AI-assisted analysis of actix/actix-web@937960ca67 (2026-08-06).
Data as JSON: /data/errors/7fd4a94463244c3c.json.
Report an issue: GitHub.