java-native-access/jna · error · IllegalArgumentException

must be set from byte[]

Error message

 must be set from byte[]

What it means

This IllegalArgumentException is thrown by Winevt.EVT_VARIANT.setValue when the variant's EvtVarType is one that requires the value to be supplied as a byte[] (raw binary data), but the caller passed a value of an incompatible Java type (e.g. a String, Integer, or pointer-like object) instead of a byte array. The library only knows how to marshal byte-backed payloads for these variant types and refuses to guess. It is a caller type error, not a Win32 failure.

Source

Thrown at contrib/platform/src/com/sun/jna/platform/win32/Winevt.java:449

                            field1.writeField("pointerValue", mem);
                        } else if (value.getClass() == double.class) {
                            Type = type.ordinal();
                            Count = 0;
                            field1.writeField("doubleVal", value);
                        } else {
                            throw new IllegalArgumentException(type.name() + " must be set from double/double[]");
                        }
                        break;
                    case EvtVarTypeBinary:
                        if (value.getClass().isArray() && value.getClass().getComponentType() == byte.class) {
                            Type = type.ordinal();
                            Memory mem = new Memory(((byte[]) value).length * 1);
                            mem.write(0, (byte[]) value, 0, ((byte[]) value).length);
                            holder = mem;
                            Count = 0;
                            field1.writeField("pointerValue", mem);
                        } else {
                            throw new IllegalArgumentException(type.name() + " must be set from byte[]");
                        }
                        break;
                    case EvtVarTypeFileTime:
                    case EvtVarTypeEvtHandle:
                    case EvtVarTypeSysTime:
                    case EvtVarTypeGuid:
                    case EvtVarTypeSid:
                    case EvtVarTypeSizeT:
                    default:
                        throw new IllegalStateException(String.format("NOT IMPLEMENTED: getValue(%s) (Array: %b, Count: %d)", type, isArray(), Count));
                }
            }
            write();
        }

        /**
         * @return value contained in the EVT_VARIANT
         */

View on GitHub (pinned to d036ad9781)

Solutions

  1. Pass a byte[] to setValue(), e.g. value.getBytes(StandardCharsets.UTF_8) for string data or a properly encoded buffer for binary data
  2. Check the variant's EvtVarType first and only supply the Java type that type maps to (map String<->EvtVarTypeString, Integer<->EvtVarTypeUInt32/Int32, byte[]<->EvtVarTypeBinary)
  3. If the target type is not byte[], change the variant type or use the appropriate setValue branch instead of forcing binary marshalling
  4. Wrap the write in try/catch (IllegalArgumentException) during config modification to fail gracefully and log the offending type

Example fix

// before
variant.setValue("604800");
// after
variant.setValue("604800".getBytes(StandardCharsets.UTF_8));
Defensive patterns

Strategy: type-guard

Validate before calling

if (!(value instanceof byte[])) {
    throw new IllegalArgumentException("EvtVarTypeBinary requires byte[], got " + value.getClass());
}

Type guard

boolean isBinaryWritable(EVT_VARIANT v, Object val) {
    return v.type == Winevt.EvtVarTypeBinary && val instanceof byte[];
}

Try / catch

try {
    variant.setValue(val);
} catch (IllegalArgumentException e) {
    log.warn("setValue type mismatch: " + e.getMessage());
}

Prevention

When it happens

Trigger: Calling EVT_VARIANT.setValue() on a variant whose type is EvtVarTypeBinary (or another byte[]-only type) with a non-byte[] argument, e.g. setValue("someString") instead of setValue(someString.getBytes()). Seen from testModifyChannelConfig when writing channel configuration values with a mismatched type.

Common situations: Setting an event-channel config property where the developer assumes String or integer values are accepted; converting config values read via getValue() (which may return String/Integer) and writing them back without converting to byte[]; JNA version changes that tightened setValue type handling.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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