apache/dubbo · error · IndexOutOfBoundsException

bytes2hex: offset + length > array length.

Error message

bytes2hex: offset + length > array length.

What it means

Thrown by Bytes.bytes2hex(byte[], int, int) when off + len exceeds the byte array length. This is the upper-bound check ensuring the requested region [off, off+len) stays within the array. It runs after the offset and length sign checks, and prevents ArrayIndexOutOfBoundsException during the conversion loop.

Solutions

  1. Recompute or clamp len against the actual current array length: len = Math.min(len, bs.length - off).
  2. Use bytes2hex(byte[]) for the full array to avoid manual region math.
  3. Ensure the array reference and its computed region are derived from the same source state.

Example fix

// before
byte[] slice = Arrays.copyOfRange(buf, 0, 10);
String hex = Bytes.bytes2hex(slice, 0, buf.length); // throws [153]: buf.length > slice.length

// after
String hex = Bytes.bytes2hex(slice, 0, slice.length);
Defensive patterns

Strategy: validation

Validate before calling

if (off + len > bs.length) len = bs.length - off; // clamp
String hex = Bytes.bytes2hex(bs, off, len);

Prevention

When it happens

Trigger: Calling Bytes.bytes2hex(bs, off, len) where off + len > bs.length. Stale array reference whose size shrank after the offset/length were computed; off-by-one where len includes one extra byte; passing array.length as offset with len > 0.

Common situations: Reusing a length computed against a larger buffer on a smaller sliced array; reading a length-prefixed field then truncating the buffer but keeping the old length; buffer reuse/recycling mismatch.

Related errors


AI-assisted analysis of apache/dubbo@3a3043227f (2026-08-14). Data as JSON: /api/errors/c0e71d9401c713aa. Report an issue: GitHub.

Appendix: source

Thrown at dubbo-common/src/main/java/org/apache/dubbo/common/io/Bytes.java:405

    }

    /**
     * to hex string.
     *
     * @param bs  byte array.
     * @param off offset.
     * @param len length.
     * @return hex string.
     */
    public static String bytes2hex(byte[] bs, int off, int len) {
        if (off < 0) {
            throw new IndexOutOfBoundsException("bytes2hex: offset < 0, offset is " + off);
        }
        if (len < 0) {
            throw new IndexOutOfBoundsException("bytes2hex: length < 0, length is " + len);
        }
        if (off + len > bs.length) {
            throw new IndexOutOfBoundsException("bytes2hex: offset + length > array length.");
        }

        byte b;
        int r = off, w = 0;
        char[] cs = new char[len * 2];
        for (int i = 0; i < len; i++) {
            b = bs[r++];
            cs[w++] = BASE16[b >> 4 & MASK4];
            cs[w++] = BASE16[b & MASK4];
        }
        return new String(cs);
    }

    /**
     * from hex string.
     *
     * @param str hex string.
     * @return byte array.

View on GitHub (pinned to 3a3043227f)