java-native-access/jna · error · IllegalArgumentException

Invalid data length:

Error message

Invalid data length: 

What it means

Validation guard in GUID.fromBinary: it fires because the byte array passed in is not exactly 16 bytes long, which is the fixed binary size of a Windows GUID (4+2+2+8 bytes). Any other length cannot be deserialized into a GUID.

Source

Thrown at contrib/platform/src/com/sun/jna/platform/win32/Guid.java:207

                && (this.Data3 == other.Data3)
                && Arrays.equals(this.Data4, other.Data4);
        }

        @Override
        public int hashCode() {
            return this.Data1 + this.Data2 & 0xFFFF + this.Data3 & 0xFFFF + Arrays.hashCode(this.Data4);
        }

        /**
         * From binary.
         *
         * @param data
         *            the data
         * @return the guid
         */
        public static GUID fromBinary(byte[] data) {
            if (data.length != 16) {
                throw new IllegalArgumentException("Invalid data length: "
                        + data.length);
            }

            GUID newGuid = new GUID();
            long data1Temp = data[0] & 0xff;
            data1Temp <<= 8;
            data1Temp |= data[1] & 0xff;
            data1Temp <<= 8;
            data1Temp |= data[2] & 0xff;
            data1Temp <<= 8;
            data1Temp |= data[3] & 0xff;
            newGuid.Data1 = (int) data1Temp;

            int data2Temp = data[4] & 0xff;
            data2Temp <<= 8;
            data2Temp |= data[5] & 0xff;
            newGuid.Data2 = (short) data2Temp;

View on GitHub (pinned to d036ad9781)

Solutions

  1. Ensure the byte array is exactly 16 bytes: slice it (Arrays.copyOfRange(data, off, off+16)) or validate data.length before calling
  2. Parse GUID strings with GUID.fromString (or fromStringIID) instead of manual byte conversion
  3. Check the serialization/source format — the producer may be writing a different structure than a raw 16-byte GUID

Example fix

// before
GUID g = GUID.fromBinary(blob);
// after
if (blob.length != 16) {
    throw new IllegalArgumentException("expected 16-byte GUID, got " + blob.length);
}
GUID g = GUID.fromBinary(Arrays.copyOfRange(blob, 0, 16));
Defensive patterns

Strategy: validation

Validate before calling

public static GUID safeFromBinary(byte[] data) {
    if (data == null || data.length != 16)
        throw new IllegalArgumentException("GUID needs exactly 16 bytes, got " + (data == null ? "null" : data.length));
    return GUID.fromBinary(data);
}

Type guard

boolean is16Bytes(byte[] b) {
    return b != null && b.length == 16;
}

Try / catch

try {
    GUID g = GUID.fromBinary(data);
} catch (IllegalArgumentException e) {
    // data.length != 16 — fix the slice/source offsets
    log.error("Bad GUID blob: " + e.getMessage());
}

Prevention

When it happens

Trigger: Passing a byte[] from a truncated buffer, a GUID string converted without accounting for formatting, or an array read from a stream with fewer/more than 16 bytes into fromBinary.

Common situations: Reading GUIDs from files or network payloads with wrong offsets; converting a 36-char UUID string to bytes directly (36 bytes) instead of parsing; mixing little-endian serialized blobs of other sizes.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12). Data as JSON: /api/errors/069509d3dd7562cc. Report an issue: GitHub.