apache/dubbo · error · IndexOutOfBoundsException

bytes2hex: length < 0, length is {}

Error message

bytes2hex: length < 0, length is {}

What it means

Thrown by Bytes.bytes2hex(byte[], int, int) when the length argument is negative. The method allocates a char[ ] of size len*2 for the hex output, so a negative length is meaningless and is rejected up front. The check runs after the offset check, so a negative offset throws first.

Source

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

     */
    public static String bytes2hex(byte[] bs) {
        return bytes2hex(bs, 0, bs.length);
    }

    /**
     * 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.

View on GitHub (pinned to 3a3043227f)

Solutions

  1. Validate length >= 0 before calling bytes2hex.
  2. Use bytes2hex(byte[]) for the whole array to avoid manual length computation.
  3. Sanitize parsed length fields from untrusted input before use.

Example fix

// before
int len = endPos - startPos; // negative if endPos < startPos
String hex = Bytes.bytes2hex(data, off, len); // throws [152]

// after
int len = Math.max(0, endPos - startPos);
if (off < 0 || off + len > data.length) throw new IllegalArgumentException();
String hex = Bytes.bytes2hex(data, off, len);
Defensive patterns

Strategy: validation

Validate before calling

if (len < 0) throw new IllegalArgumentException("negative length: " + len);
String hex = Bytes.bytes2hex(bs, off, len);

Prevention

When it happens

Trigger: Calling Bytes.bytes2hex(bs, off, len) with len < 0. Common when len is computed as (end - start) where end < start, or when an uninitialized/decoded length field is negative.

Common situations: Length derived from a packet field whose value was corrupt or negative; arithmetic producing a negative remainder; passing a length variable defaulting to -1 as an 'unset' sentinel.

Related errors


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