java-native-access/jna · error · IllegalArgumentException
Argument value 0x exceeds native capacity ( bytes) mask=0x
Error message
Argument value 0x<value> exceeds native capacity (<size> bytes) mask=0x<mask>
What it means
IntegerType.setValue throws this IllegalArgumentException when a value does not fit in the declared native width: for unsigned types the value exceeds the mask of the size in bytes, or a negative value is not representable after truncation. It protects against silently truncating values when crossing the Java/native boundary.
Solutions
- Mask the value before assignment: value & 0xFFFFFFFFL for a 4-byte unsigned type.
- Use the signed variant (e.g. SWORD instead of UWORD) if negative values are legal.
- Widen the type (e.g. use an 8-byte NativeLong/Long type) if values genuinely exceed capacity.
Example fix
// before new UINT(value); // value = 0x1_FFFF_FFFFL, > 4 bytes // after new UINT(value & 0xFFFFFFFFL);
Defensive patterns
Strategy: validation
Validate before calling
static long maskFor(int sizeBytes) { return sizeBytes >= 8 ? ~0L : (1L << (sizeBytes * 8)) - 1; }
static long checkedUnsigned(long value, int sizeBytes) {
long m = maskFor(sizeBytes);
if ((value & ~m) != 0 && value >= 0) throw new IllegalArgumentException("0x" + Long.toHexString(value) + " > " + sizeBytes + " bytes");
return value & m;
} Try / catch
try {
new ULONG(rawValue);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("exceeds native capacity")) {
throw new IllegalStateException("Value 0x" + Long.toHexString(rawValue) + " does not fit; mask before constructing", e);
}
throw e;
} Prevention
- Mask values (& 0xFF/0xFFFF/0xFFFFFFFFL) before constructing unsigned types.
- Use signed IntegerType subclasses when negative values are expected.
- Never do arithmetic that can overflow before constructing the type.
- Model unsigned 64-bit values carefully; long is signed in Java.
When it happens
Trigger: new ULONG(-1) or new UINT32(0xFFFFFFFFL + 1) style calls; passing a long larger than the type's capacity (e.g. 2^40 into a 4-byte type); fromNative receiving a value with bits set above size*8.
Common situations: Storing unsigned constants in signed Java longs (e.g. 0xFFFFFFFF for a 4-byte unsigned type is fine, but -1 is not); arithmetic overflow before constructing the type; mixing up signed/unsigned IntegerType subclasses.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- Unsupported size
- Allocation size must be greater than zero
- Area is not polygonal: " + area
- Array fields must be initialized
- Arrays of length zero not allowed: type
AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12).
Data as JSON: /api/errors/13de1dda1d61e31d.
Report an issue: GitHub.
Appendix: source
Thrown at src/com/sun/jna/IntegerType.java:110
break;
case 4:
if (unsigned) {
this.value = value & 0xFFFFFFFFL;
}
truncated = (int) value;
this.number = Integer.valueOf((int) value);
break;
case 8:
this.number = Long.valueOf(value);
break;
default:
throw new IllegalArgumentException("Unsupported size: " + size);
}
if (size < 8) {
long mask = ~((1L << (size * 8)) - 1);
if ((value < 0 && truncated != value)
|| (value >= 0 && (mask & value) != 0)) {
throw new IllegalArgumentException("Argument value 0x"
+ Long.toHexString(value) + " exceeds native capacity ("
+ size + " bytes) mask=0x" + Long.toHexString(mask));
}
}
}
@Override
public Object toNative() {
return number;
}
@Override
public Object fromNative(Object nativeValue, FromNativeContext context) {
// be forgiving of null values read from memory
long value = nativeValue == null
? 0 : ((Number) nativeValue).longValue();
IntegerType number = Klass.newInstance(getClass());
number.setValue(value);View on GitHub (pinned to d036ad9781)