{"record":{"id":"ff68a6494a7616de","repo":"n0-computer/iroh","slug":"exceedsmaxpacketsize-ff68a6","errorCode":"ExceedsMaxPacketSize","errorMessage":"Packet exceeds max packet size","messagePattern":"Packet exceeds max packet size","errorType":"validation","errorClass":"SendError","httpStatus":null,"severity":"error","filePath":"iroh-relay/src/server/streams.rs","lineNumber":132,"sourceCode":"    },\n    /// Attempted to send an empty packet\n    #[error(\"Attempted to send empty packet\")]\n    EmptyPacket {},\n}\n\nimpl<S> Sink<RelayToClientMsg> for RelayedStream<S>\nwhere\n    S: Sink<bytes::Bytes, Error = StreamError> + Unpin,\n{\n    type Error = SendError;\n\n    fn poll_ready(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {\n        Pin::new(&mut self.inner).poll_ready(cx).map_err(Into::into)\n    }\n\n    fn start_send(mut self: Pin<&mut Self>, item: RelayToClientMsg) -> Result<(), Self::Error> {\n        let size = item.encoded_len();\n        ensure!(\n            size <= MAX_PACKET_SIZE,\n            SendError::ExceedsMaxPacketSize { size }\n        );\n        if let RelayToClientMsg::Datagrams { datagrams, .. } = &item {\n            ensure!(!datagrams.contents.is_empty(), SendError::EmptyPacket);\n        }\n\n        Pin::new(&mut self.inner)\n            .start_send(item.to_bytes().freeze())\n            .map_err(Into::into)\n    }\n\n    fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {\n        Pin::new(&mut self.inner).poll_flush(cx).map_err(Into::into)\n    }\n\n    fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {\n        Pin::new(&mut self.inner).poll_close(cx).map_err(Into::into)","sourceCodeStart":114,"sourceCodeEnd":150,"githubUrl":"https://github.com/n0-computer/iroh/blob/2b4de030ce5e0133f272871a76f0c685c63f552a/iroh-relay/src/server/streams.rs#L114-L150","documentation":"The relay server tried to send a RelayToClientMsg to a connected client whose encoded size exceeds MAX_PACKET_SIZE. Sending is aborted in start_send before the packet hits the wire, returning SendError::ExceedsMaxPacketSize with the offending size.","triggerScenarios":"Producing a RelayToClientMsg::Datagrams (or other relay-to-client message) whose encoded length is greater than MAX_PACKET_SIZE, e.g. by batching too many/large datagrams into one packet, then passing it through the client send sink.","commonSituations":"Applications that accumulate many datagrams before flushing, large payload batching across a relay connection, misconfigured MTU/packet-size assumptions when porting code between direct and relayed connections.","solutions":["Split the message into multiple packets so each encoded packet stays within MAX_PACKET_SIZE.","Reduce the number of datagrams batched into a single RelayToClientMsg::Datagrams.","Check item.encoded_len() before enqueueing and chunk accordingly.","Compress or shrink payloads before sending over the relay."],"exampleFix":"// before\nsink.start_send(big_msg).await?; // may exceed MAX_PACKET_SIZE\n// after\nfor chunk in chunk_by_encoded_len(big_msg, MAX_PACKET_SIZE) {\n    sink.start_send(chunk).await?;\n}","handlingStrategy":"validation","validationCode":"fn fits_in_packet(msg: &RelayToClientMsg) -> bool { msg.encoded_len() <= MAX_PACKET_SIZE }","typeGuard":"fn valid_packet(msg: RelayToClientMsg) -> Option<RelayToClientMsg> { (msg.encoded_len() <= MAX_PACKET_SIZE).then_some(msg) }","tryCatchPattern":"match sink.start_send(item) {\n    Err(SendError::ExceedsMaxPacketSize { size }) => { chunk_and_resend(size); }\n    other => other?,\n}","preventionTips":["Check encoded_len() before enqueueing every relay packet.","Cap the number of datagrams batched per message.","Add unit tests asserting max-size invariants.","Centralize packet construction in one helper that enforces the limit."],"tags":["relay","packet-size","limit-exceeded","network"],"backgroundTag":"payload-too-large","analyzedSha":"2b4de030ce5e0133f272871a76f0c685c63f552a","analyzedAt":"2026-09-08T04:26:47.755Z","contentChangedAt":"2026-09-08T04:26:47.755Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}