denoland/deno · error · RangeError

Buffer size must be a multiple of 64-bits

Error message

Buffer size must be a multiple of 64-bits

What it means

Buffer.prototype.swap64() reverses bytes in place in 8-byte groups (64-bit endianness flip used for doubles, BigInt64, f64 arrays). If the byte length is not a multiple of 8 the buffer cannot be split into whole 64-bit words, so a plain RangeError is thrown before any modification. Same as Node.

Source

Thrown at ext/node/polyfills/internal/buffer.mjs:694

  return this;
};

Buffer.prototype.swap32 = function swap32() {
  const len = this.length;
  if (len % 4 !== 0) {
    throw new RangeError("Buffer size must be a multiple of 32-bits");
  }
  for (let i = 0; i < len; i += 4) {
    swap(this, i, i + 3);
    swap(this, i + 1, i + 2);
  }
  return this;
};

Buffer.prototype.swap64 = function swap64() {
  const len = this.length;
  if (len % 8 !== 0) {
    throw new RangeError("Buffer size must be a multiple of 64-bits");
  }
  for (let i = 0; i < len; i += 8) {
    swap(this, i, i + 7);
    swap(this, i + 1, i + 6);
    swap(this, i + 2, i + 5);
    swap(this, i + 3, i + 4);
  }
  return this;
};

function decodeUtf8(buffer, start, end) {
  return op_node_encoding_slice(
    buffer,
    start,
    end,
    0,
  );
}

View on GitHub (pinned to 9ad36f7a2c)

Solutions

  1. Check length % 8 === 0 first and report the remainder as truncation
  2. Trim to an 8-byte boundary for padded formats: buf.subarray(0, buf.length - buf.length % 8).swap64()
  3. Re-check the framing arithmetic that produced the buffer - a wrong length prefix is the usual root cause
  4. Pad explicitly to the next multiple of 8 when the format requires it

Example fix

// before
const buf = Buffer.alloc(12);
buf.swap64(); // RangeError: Buffer size must be a multiple of 64-bits

// after
const usable = buf.length - (buf.length % 8);
buf.subarray(0, usable).swap64(); // swaps the first 8 bytes
Defensive patterns

Strategy: validation

Validate before calling

function swap64Safe(buf) {
  if (buf.length % 8 !== 0) {
    throw new RangeError(`expected byte length divisible by 8, got ${buf.length}`);
  }
  return buf.swap64();
}

Try / catch

try {
  buf.swap64();
} catch (e) {
  if (e instanceof RangeError) { /* trim to 8-byte boundary or refetch the record */ }
  else throw e;
}

Prevention

When it happens

Trigger: buf.swap64() when buf.length % 8 !== 0, e.g. Buffer.alloc(12).swap64() or a 20-byte payload of f64 values after a partial socket read.

Common situations: Converting arrays of 64-bit doubles or BigInt64 between endian formats; binary protocols with 8-byte fields where a short read left length % 8 != 0; buffers assembled from chunks whose total length was never re-validated.

Related errors


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/8f11f2a5a8bbf6b7. Report an issue: GitHub.