decolua/9router · error

AWS EventStream header exceeds its declared bounds

Error message

AWS EventStream header exceeds its declared bounds

What it means

parseEventFrame() decodes binary AWS EventStream frames (the wire format Kiro's upstream uses instead of plain SSE). Before reading each header entry it calls requireBytes(count), which throws this error when the bytes needed for a header name/type/value would run past the frame's declared headers section (offset 12 .. 12+headersLength). The library throws it to signal a malformed or corrupted frame rather than reading out of bounds or returning garbage headers.

Source

Thrown at open-sse/executors/kiro.js:1224

  if (totalLength > EVENTSTREAM_MAX_MESSAGE_BYTES ||
      headersLength > EVENTSTREAM_MAX_HEADERS_BYTES ||
      headersLength > totalLength - 16) {
    throw new Error("AWS EventStream frame bounds are invalid");
  }
  if (view.getUint32(8, false) !== crc32(data.subarray(0, 8))) {
    throw new Error("AWS EventStream prelude CRC mismatch");
  }
  if (view.getUint32(totalLength - 4, false) !== crc32(data.subarray(0, totalLength - 4))) {
    throw new Error("AWS EventStream message CRC mismatch");
  }

  const headers = Object.create(null);
  const names = new Set();
  let offset = 12;
  const headerEnd = offset + headersLength;
  const requireBytes = (count) => {
    if (offset + count > headerEnd) {
      throw new Error("AWS EventStream header exceeds its declared bounds");
    }
  };

  while (offset < headerEnd) {
    requireBytes(1);
    const nameLength = data[offset++];
    requireBytes(nameLength + 1);
    const name = decoder.decode(data.subarray(offset, offset + nameLength));
    offset += nameLength;
    if (names.has(name)) throw new Error(`AWS EventStream contains duplicate header: ${name}`);
    names.add(name);
    const type = data[offset++];

    if (type === 0 || type === 1) {
      headers[name] = type === 0;
    } else if (type === 2) {
      requireBytes(1);
      headers[name] = view.getInt8(offset);

View on GitHub (pinned to 90b52e06ff)

Solutions

  1. Check for an HTTP proxy/MITM (corporate proxy, VPN, undici ProxyAgent) that rewrites or truncates binary responses and bypass it or whitelist the Kiro endpoint
  2. Retry the request — transient stream corruption from the upstream network usually clears on a fresh attempt
  3. Update 9router to the latest version in case Kiro changed its EventStream encoding and the parser was fixed
  4. Capture the raw frame (log data as base64/hex before parseEventFrame) and compare against AWS EventStream spec to confirm malformed input
  5. If persistent, the credential/endpoint may be routing to a non-EventStream endpoint — re-authenticate the Kiro account

Example fix

// before
catch (e) { if (e.message.includes('EventStream')) return res.status(502); }
// after
catch (e) {
  if (e.message.includes('header exceeds its declared bounds')) {
    return accountFallback.retry({ reason: 'eventstream-corruption' });
  }
  throw e;
}
Defensive patterns

Strategy: retry

Validate before calling

// cannot pre-validate binary frames; validate input type before parse
if (!(chunk instanceof Uint8Array) || chunk.byteLength < 16) {
  throw new Error('invalid eventstream chunk');
}

Try / catch

try {
  await executor.execute(req);
} catch (e) {
  if (String(e.message).includes('EventStream')) {
    // treat as upstream corruption — retry once, then fall back to another account
    return retryOnceThenFallback(req);
  }
  throw e;
}

Prevention

When it happens

Trigger: An EventStream frame arrives whose header-encoded length bytes imply a header entry extending beyond headersLength — i.e. truncated/corrupted binary data, a frame assembled with wrong offsets, or an upstream that changed its header encoding. The check fires on the name-length byte, the name bytes, the type byte, or any fixed-size value read.

Common situations: Proxy or middleware in front of the gateway truncates or re-chunks the binary stream (some proxies mangle non-UTF8 bodies); a Kiro protocol/version change; an upstream returning an HTML/JSON error page that partially overlaps frame boundaries after a failed length check.

Related errors


AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30). Data as JSON: /api/errors/33a3590c1f65fc29. Report an issue: GitHub.