java-native-access/jna · error · IllegalArgumentException
CFString conversion fails or the provided buffer is too…
Error message
CFString conversion fails or the provided buffer is too small.
What it means
CFStringRef.stringValue() converts a CoreFoundation string to a Java String via CFStringGetCString into a UTF-8 buffer sized from CFStringGetMaximumCStringSize plus 1. If the conversion fails (invalid CFString, embedded nulls, or the buffer was somehow too small), CFStringGetCString returns 0 and this IllegalArgumentException is thrown.
Solutions
- Verify the dictionary value is actually a CFString before casting (check CFGetTypeID against CFStringGetTypeID())
- Wrap stringValue() in try-catch for IllegalArgumentException and fall back to an empty/default string
- Check that the CFStringRef pointer is non-null (ref.equals(Pointer.NULL) is false) before calling stringValue()
Example fix
// before
String name = cfDictionaryRef.getStringProperty(key);
// after
String name;
try {
name = cfDictionaryRef.getStringProperty(key);
} catch (IllegalArgumentException e) {
name = ""; // value was not a convertible CFString
} Defensive patterns
Strategy: try-catch
Validate before calling
// check pointer validity first
if (cfStringRef == null || cfStringRef.getPointer() == null || Pointer.NULL.equals(cfStringRef.getPointer())) {
throw new IllegalArgumentException("CFStringRef has no valid pointer");
} Type guard
boolean isConvertible(CFStringRef s) { return s != null && s.getPointer() != null; } Try / catch
try { value = cfString.stringValue(); } catch (IllegalArgumentException e) { value = ""; } Prevention
- Confirm the source API actually returns a CFString before casting to CFStringRef
- Never call stringValue() on a default-constructed or released CFStringRef
- Wrap stringValue() in a helper that returns Optional<String>
When it happens
Trigger: Calling stringValue() on a CFStringRef whose native pointer is invalid or whose content cannot be encoded to UTF-8 as a C string; callers include getStringProperty on CFDictionary values, window list descriptions, and locale date/time formats where a key holds a non-string value.
Common situations: Reading a CFDictionary property that does not actually contain a CFString (e.g. a CFNumber or CFBoolean cast as CFStringRef); corrupted or already-released CFString references from CoreGraphics/CoreFoundation APIs; macOS API changes returning unexpected types.
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
- Unable to cast to CFArray. Type ID
- Unable to cast to CFBoolean. Type ID
- Unable to cast to CFData. Type ID
- Unable to cast to CFDictionary. Type ID
- Unable to cast to CFDictionary. Type ID
AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12).
Data as JSON: /api/errors/deb9120824940c8d.
Report an issue: GitHub.
Appendix: source
Thrown at contrib/platform/src/com/sun/jna/platform/mac/CoreFoundation.java:588
// Get number of characters (UTF-16 code pairs)
// Code points > 0xffff will have 2 characters per Unicode character
CFIndex length = INSTANCE.CFStringGetLength(this);
if (length.longValue() == 0) {
return "";
}
// Calculate maximum possible size in UTF8 bytes
// This will be 3 x length
CFIndex maxSize = INSTANCE.CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8);
if (maxSize.intValue() == kCFNotFound) {
throw new StringIndexOutOfBoundsException("CFString maximum number of bytes exceeds LONG_MAX.");
}
// Increment size by 1 for a null byte
maxSize.setValue(maxSize.longValue() + 1);
Memory buf = new Memory(maxSize.longValue());
if (0 != INSTANCE.CFStringGetCString(this, buf, maxSize, kCFStringEncodingUTF8)) {
return buf.getString(0, "UTF8");
}
throw new IllegalArgumentException("CFString conversion fails or the provided buffer is too small.");
}
}
/**
* A wrapper for the {@link NativeLong} type, used for {@link CFNumberRef}
* types, {@link CFStringRef} lengths, and {@link CFArrayRef} sizes and indices.
*/
class CFIndex extends NativeLong {
private static final long serialVersionUID = 1L;
public CFIndex() {
super();
}
public CFIndex(long value) {
super(value);
}
}View on GitHub (pinned to d036ad9781)