java-native-access/jna · error · Error
Field alignment is zero for field '" + structField.name +…
Error message
Field alignment is zero for field '" + structField.name + "' within " + getClass()
What it means
During layout, the computed alignment for a field was zero, which is impossible for any valid native type. JNA treats this as an internal invariant violation and throws Error, naming the field and Structure class.
Solutions
- Fix the custom NativeMapped.nativeSize() implementation to return a positive value
- Correct the TypeMapper so mapped types report a valid positive native size
- Audit any JNA subclasses overriding size/alignment calculation
- If using stock types, report/reproduce with a minimal structure — this signals a JNA internals bug
Example fix
// before
public int nativeSize() { return 0; }
// after
public int nativeSize() { return 4; } Defensive patterns
Strategy: type-guard
Validate before calling
for (Field f : S.class.getFields()) {
Class<?> t = f.getType();
if (NativeMapped.class.isAssignableFrom(t)) {
try {
NativeMapped nm = (NativeMapped) t.getDeclaredConstructor().newInstance();
if (((Integer) nm.getClass().getMethod("nativeSize").invoke(nm)) <= 0) {
throw new IllegalStateException("nativeSize must be > 0 for " + t);
}
} catch (ReflectiveOperationException e) { throw new IllegalStateException(e); }
}
} Type guard
static boolean hasPositiveNativeSize(Class<?> t) {
if (!NativeMapped.class.isAssignableFrom(t)) return true;
try {
Object inst = t.getDeclaredConstructor().newInstance();
Object sz = t.getMethod("nativeSize").invoke(inst);
return sz instanceof Integer && (Integer) sz > 0;
} catch (ReflectiveOperationException e) { return false; }
} Try / catch
try {
s.size();
} catch (Error e) {
if (e.getMessage() != null && e.getMessage().contains("alignment is zero")) {
throw new IllegalStateException("Fix zero-size mapping: " + e.getMessage(), e);
}
throw e;
} Prevention
- Never return 0 from NativeMapped.nativeSize()
- Audit custom TypeMappers for zero-sized conversions
- Keep alignment logic in stock JNA unless unavoidable
- Add nativeSize assertions in mapper unit tests
When it happens
Trigger: fieldAlignment derived from the field's native size/data ends up 0 — typically a zero-sized or mis-sized field type produced by a custom TypeMapper/NativeMapped returning nativeSize 0, or a corrupted alignment calculation path.
Common situations: Custom NativeMapped implementations whose nativeSize() returns 0; buggy custom TypeMappers; extending/overriding JNA internals that feed alignment calculation.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Type " + type + " has unknown native alignment"
- Array fields must be initialized
- Byte boundary must be a power of two
- Byte boundary must be positive
- Can't determine size of nested structure
AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12).
Data as JSON: /api/errors/7785828a73816c49.
Report an issue: GitHub.
Appendix: source
Thrown at src/com/sun/jna/Structure.java:1442
value = initializeField(structField.field, type);
}
try {
structField.size = getNativeSize(nativeType, value);
fieldAlignment = getNativeAlignment(nativeType, value, firstField);
}
catch(IllegalArgumentException e) {
// Might simply not yet have a type mapper set yet
if (!force && typeMapper == null) {
return null;
}
String msg = "Invalid Structure field in " + getClass() + ", field name '" + structField.name + "' (" + structField.type + "): " + e.getMessage();
throw new IllegalArgumentException(msg, e);
}
// Align fields as appropriate
if (fieldAlignment == 0) {
throw new Error("Field alignment is zero for field '" + structField.name + "' within " + getClass());
}
info.alignment = Math.max(info.alignment, fieldAlignment);
if ((calculatedSize % fieldAlignment) != 0) {
calculatedSize += fieldAlignment - (calculatedSize % fieldAlignment);
}
if (this instanceof Union) {
structField.offset = 0;
calculatedSize = Math.max(calculatedSize, structField.size);
}
else {
structField.offset = calculatedSize;
calculatedSize += structField.size;
}
// Save the field in our list
info.fields.put(structField.name, structField);
}
View on GitHub (pinned to d036ad9781)