TooTallNate/Java-WebSocket · error · IllegalArgumentException

Cannot have offset of

Error message

Cannot have offset of %d and length of %d with array of length %d

What it means

encodeBytesToBytes verifies that the requested slice off+len fits within the source array. When it would read past the end, the library throws IllegalArgumentException with the offending offset, length, and array length. It protects against out-of-bounds reads that would otherwise throw ArrayIndexOutOfBoundsException deeper in the encoder.

Solutions

  1. Clamp the slice: len = Math.min(len, source.length - off) before encoding.
  2. Assert off >= 0 && off + len <= source.length before the call.
  3. If the length comes from external data, validate it against source.length at the deserialization boundary.

Example fix

// before
byte[] out = Base64.encodeBytesToBytes(data, off, len);

// after
if (off < 0 || len < 0 || off + len > data.length) {
    throw new IllegalArgumentException("slice out of bounds");
}
byte[] out = Base64.encodeBytesToBytes(data, off, len);
Defensive patterns

Strategy: validation

Validate before calling

if (data != null && off >= 0 && len >= 0 && off + len <= data.length) {
    byte[] out = Base64.encodeBytesToBytes(data, off, len);
}

Type guard

static boolean inBounds(byte[] a, int off, int len) {
    return a != null && off >= 0 && len >= 0 && off <= a.length && len <= a.length - off;
}

Try / catch

try {
    out = Base64.encodeBytesToBytes(data, off, len);
} catch (IllegalArgumentException e) {
    logger.warn("encode slice out of bounds: " + e.getMessage());
    out = EMPTY;
}

Prevention

When it happens

Trigger: Calling encodeBytesToBytes(source, off, len) where off + len > source.length, e.g. passing a length measured in a different unit (chars vs bytes) or reusing a length from another array.

Common situations: Copying a cached length from a previous larger buffer; off-by-one when the length was meant to be source.length - off; encoding a subrange after the array was reallocated smaller.

Related errors


AI-assisted analysis of TooTallNate/Java-WebSocket@afeacbf8c0 (2026-09-09). Data as JSON: /api/errors/84671735e5fe9f28. Report an issue: GitHub.

Appendix: source

Thrown at src/main/java/org/java_websocket/util/Base64.java:664

   * @since 2.3.1
   */
  public static byte[] encodeBytesToBytes(byte[] source, int off, int len, int options)
      throws java.io.IOException {

    if (source == null) {
      throw new IllegalArgumentException("Cannot serialize a null array.");
    }   // end if: null

    if (off < 0) {
      throw new IllegalArgumentException("Cannot have negative offset: " + off);
    }   // end if: off < 0

    if (len < 0) {
      throw new IllegalArgumentException("Cannot have length offset: " + len);
    }   // end if: len < 0

    if (off + len > source.length) {
      throw new IllegalArgumentException(
          String
              .format("Cannot have offset of %d and length of %d with array of length %d", off, len,
                  source.length));
    }   // end if: off < 0

    // Compress?
    if ((options & GZIP) != 0) {
      java.io.ByteArrayOutputStream baos = null;
      java.util.zip.GZIPOutputStream gzos = null;
      Base64.OutputStream b64os = null;

      try {
        // GZip -> Base64 -> ByteArray
        baos = new java.io.ByteArrayOutputStream();
        b64os = new Base64.OutputStream(baos, ENCODE | options);
        gzos = new java.util.zip.GZIPOutputStream(b64os);

        gzos.write(source, off, len);

View on GitHub (pinned to afeacbf8c0)