java-native-access/jna · error · RuntimeException
LookupAccountNameW was expected to fail with ERROR_INSUFFICI
Error message
LookupAccountNameW was expected to fail with ERROR_INSUFFICIENT_BUFFER
What it means
Advapi32Util.getAccountByName first calls LookupAccountNameW with null buffers purely to query the required SID and domain-name buffer sizes; the Win32 contract says this probe call must fail with ERROR_INSUFFICIENT_BUFFER. This RuntimeException is thrown when the probe unexpectedly SUCCEEDS, meaning JNA's two-call size-probe protocol invariant was violated. It almost always indicates an OS/JNA mapping mismatch rather than bad user input.
Source
Thrown at contrib/platform/src/com/sun/jna/platform/win32/Advapi32Util.java:198
}
/**
* Retrieves a security identifier (SID) for a given account.
*
* @param systemName
* Name of the system.
* @param accountName
* Account name.
* @return A structure containing the account SID.
*/
public static Account getAccountByName(String systemName, String accountName) {
IntByReference pSid = new IntByReference(0);
IntByReference cchDomainName = new IntByReference(0);
PointerByReference peUse = new PointerByReference();
if (Advapi32.INSTANCE.LookupAccountName(systemName, accountName, null,
pSid, null, cchDomainName, peUse)) {
throw new RuntimeException(
"LookupAccountNameW was expected to fail with ERROR_INSUFFICIENT_BUFFER");
}
int rc = Kernel32.INSTANCE.GetLastError();
if (pSid.getValue() == 0 || rc != W32Errors.ERROR_INSUFFICIENT_BUFFER) {
throw new Win32Exception(rc);
}
Memory sidMemory = new Memory(pSid.getValue());
PSID result = new PSID(sidMemory);
char[] referencedDomainName = new char[cchDomainName.getValue() + 1];
if (!Advapi32.INSTANCE.LookupAccountName(systemName, accountName,
result, pSid, referencedDomainName, cchDomainName, peUse)) {
throw new Win32Exception(Kernel32.INSTANCE.GetLastError());
}
Account account = new Account();View on GitHub (pinned to d036ad9781)
Solutions
- Verify you are running on a real Windows platform with a matching jna-platform version; upgrade com.sun.jna:jna-platform to the latest release
- Check the accountName string - trim whitespace and pass a plain account name (e.g. 'Administrators') rather than an empty or special string
- If it happens in tests, ensure the Advapi32 mock/stub follows the real contract: null-buffer call must fail with ERROR_INSUFFICIENT_BUFFER
- Report to JNA if a specific Windows build makes the sizing call return TRUE; meanwhile call LookupAccountName once with a large preallocated buffer instead of the two-call pattern
Example fix
// before (library internals - workaround on caller side)
Account a = Advapi32Util.getAccountByName(null, userName);
// after - guard the input first
if (userName == null || userName.trim().isEmpty()) {
throw new IllegalArgumentException("accountName must be a non-empty Windows account name");
}
Account a = Advapi32Util.getAccountByName(null, userName); Defensive patterns
Strategy: validation
Validate before calling
if (accountName == null || accountName.trim().isEmpty()) {
throw new IllegalArgumentException("accountName must be a non-empty Windows account name");
}
if (!Platform.isWindows()) {
throw new UnsupportedOperationException("getAccountByName requires Windows");
} Try / catch
try {
Account a = Advapi32Util.getAccountByName(systemName, accountName);
} catch (RuntimeException | Win32Exception e) {
// invariant violation: report/log, do not retry blindly
throw new IllegalStateException("SID size-probe contract violated", e);
} Prevention
- Run only on supported Windows versions with a current jna-platform build
- Keep jna and jna-platform artifacts at the same version
- Never mock Advapi32 in tests without honoring the ERROR_INSUFFICIENT_BUFFER sizing contract
- Validate accountName format before invoking the API
When it happens
Trigger: Advapi32.INSTANCE.LookupAccountName(systemName, accountName, null, pSid, null, cchDomainName, peUse) returns TRUE on the sizing call, so the expected failure path never runs and the RuntimeException at Advapi32Util.java:198 is thrown.
Common situations: Running on a Windows version or non-Windows stub where the underlying LookupAccountNameW behaves differently than the documented contract; passing an account name whose resolution needs no buffer; JNA native-mapping bugs or tests running against a mocked Advapi32 that returns success for null-buffer calls.
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
- Expected GetTokenInformation to fail with ERROR_INSUFFICIENT
- Failed to find privilege "{privilege}" - {GetLastError}
- Win32Exception from native GetLastError after ExpandEnvironm
- Win32Exception from native GetLastError after ExpandEnvironm
- Win32Exception from native GetLastError when GetPriorityClas
AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12).
Data as JSON: /api/errors/5e36966e3f8b111f.
Report an issue: GitHub.