astrid-runtime/astrid · error

IPC frame too large: {len} bytes

Error message

IPC frame too large: {len} bytes

What it means

The IPC framing reader reads a 4-byte big-endian length prefix and rejects any frame whose payload length exceeds MAX_FRAME_BYTES, returning InvalidData. This prevents a corrupt or hostile peer from causing an unbounded memory allocation for a single message.

Source

Thrown at crates/astrid-uplink/src/native/framing.rs:36

        }
    }

    /// Read one length-prefixed message while retaining partial frame state.
    ///
    /// `AsyncReadExt::read` is cancellation-safe, and all bytes returned by a
    /// completed read are appended before the next await. Recreating this
    /// future after another `select!` branch wins therefore cannot discard a
    /// partially received prefix or body.
    pub(super) async fn read_message(&mut self) -> std::io::Result<Option<IpcMessage>> {
        loop {
            if self.buffered.len() >= 4 {
                let len = u32::from_be_bytes(
                    self.buffered[..4]
                        .try_into()
                        .expect("four-byte frame prefix"),
                ) as usize;
                if len > MAX_FRAME_BYTES {
                    return Err(std::io::Error::new(
                        std::io::ErrorKind::InvalidData,
                        format!("IPC frame too large: {len} bytes"),
                    ));
                }
                let frame_len = 4_usize.checked_add(len).ok_or_else(|| {
                    std::io::Error::new(std::io::ErrorKind::InvalidData, "IPC frame overflow")
                })?;
                if self.buffered.len() >= frame_len {
                    let message =
                        serde_json::from_slice(&self.buffered[4..frame_len]).map_err(|error| {
                            std::io::Error::new(
                                std::io::ErrorKind::InvalidData,
                                format!("invalid IPC message: {error}"),
                            )
                        })?;
                    self.buffered.drain(..frame_len);
                    return Ok(Some(message));
                }

View on GitHub (pinned to affd8760f4)

Solutions

  1. Resynchronize the stream (discard the connection and reconnect) — once misaligned, every subsequent frame fails.
  2. Ensure the peer respects the same MAX_FRAME_BYTES limit; chunk oversized messages on the sender side.
  3. Verify the sender always writes the 4-byte big-endian length prefix before each payload (use the library's write path, not raw I/O).
  4. Check the transport for corruption/truncation; add an outer integrity check if the channel is unreliable.

Example fix

// before
stream.write_all(&big_payload).await?; // no prefix / oversized
// after
for chunk in big_payload.chunks(MAX_FRAME_BYTES) {
    framed.write_message(chunk).await?; // library framing, within limit
}
Defensive patterns

Strategy: try-catch

Validate before calling

// before sending: enforce the frame limit on the sender side
if payload.len() > MAX_FRAME_BYTES {
    return Err("payload must be chunked to fit MAX_FRAME_BYTES");
}

Try / catch

match framed.read_message().await {
    Err(e) if e.kind() == io::ErrorKind::InvalidData && e.to_string().contains("IPC frame too large") => {
        // framing desynced or peer violates the limit: drop and re-establish the connection
        connection.reset().await?;
    }
    other => other?,
}

Prevention

When it happens

Trigger: read_message encounters a length prefix whose decoded value is greater than MAX_FRAME_BYTES — the peer sent a larger-than-allowed frame, the stream is misaligned (reading payload bytes as a length), or sender and receiver use different MAX_FRAME_BYTES limits.

Common situations: Desynchronized stream after a partial read or a skipped byte (everything after reads as garbage lengths); peer library version with a larger frame limit; protocol misuse such as writing raw bytes without the length prefix; corrupted transport (pipe/socket) flipping length bytes.

Understand the failure class

Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.

Related errors


AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09). Data as JSON: /api/errors/eec94fef0f2f5e03. Report an issue: GitHub.