herdrdev/herdr · warning · io::Error

encoded clipboard image exceeds protocol limit

Error message

encoded clipboard image exceeds protocol limit

What it means

A clipboard image being encoded for the remote/protocol path exceeded the hard byte cap enforced by LimitedWriter. The writer counts appended bytes and refuses any write that would push the encoded payload past the configured protocol limit, failing with ErrorKind::FileTooLarge. This protects the wire protocol from oversized image frames.

Source

Thrown at src/platform/windows/clipboard_image.rs:317

}

impl LimitedWriter {
    fn new(limit: usize) -> Self {
        Self {
            bytes: Vec::new(),
            limit,
        }
    }

    fn into_inner(self) -> Vec<u8> {
        self.bytes
    }
}

impl io::Write for LimitedWriter {
    fn write(&mut self, bytes: &[u8]) -> io::Result<usize> {
        if bytes.len() > self.limit.saturating_sub(self.bytes.len()) {
            return Err(io::Error::new(
                io::ErrorKind::FileTooLarge,
                "encoded clipboard image exceeds protocol limit",
            ));
        }
        self.bytes.extend_from_slice(bytes);
        Ok(bytes.len())
    }

    fn flush(&mut self) -> io::Result<()> {
        Ok(())
    }
}

fn read_u16_le(bytes: &[u8], offset: usize) -> Option<u16> {
    Some(u16::from_le_bytes(
        bytes.get(offset..offset + 2)?.try_into().ok()?,
    ))
}

View on GitHub (pinned to f457cff4f2)

Solutions

  1. Reduce the clipboard image size before encoding (crop, downscale, or lower resolution) so the encoded bytes fit under the protocol limit
  2. Compress/re-encode the image (e.g. PNG optimization or lossy format) to shrink payload size
  3. Check what limit is configured for the protocol path and raise it if your deployment can tolerate larger frames
  4. Skip image sync for oversized payloads and fall back to text-only clipboard transfer

Example fix

// before: copying a full 4K screenshot fails during encode
let mut w = LimitedWriter::new(limit);
image.write_encoder().encode(&mut w)?; // FileTooLarge

// after: downscale before encoding so payload fits
let scaled = image.resize_to_fit(max_dim);
let mut w = LimitedWriter::new(limit);
scaled.write_encoder().encode(&mut w)?;
Defensive patterns

Strategy: validation

Validate before calling

// Before syncing clipboard, estimate encoded size and skip if too large
let encoded_len = estimate_encoded_len(&image);
if encoded_len > protocol_limit { skip_image_sync_or_downscale(&image); }

Try / catch

match encode_clipboard_image(img, limit) {
    Ok(bytes) => send(bytes),
    Err(e) if e.kind() == std::io::ErrorKind::FileTooLarge => { /* downscale and retry, or send text-only */ }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling the Windows clipboard image encode path with a large screen capture or image paste while a client/protocol limit is configured, so that the encoded PNG/data bytes exceed LimitedWriter's limit during io::Write::write.

Common situations: Copying full-screen or multi-monitor screenshots, high-DPI captures, or very large images on Windows and attempting to sync them through Herdr's protocol; smaller images work but large ones fail deterministically.

Related errors


AI-assisted analysis of herdrdev/herdr@f457cff4f2 (2026-08-28). Data as JSON: /api/errors/d8f83ec2507dc203. Report an issue: GitHub.