java-native-access/jna · error · IllegalArgumentException
DACL is invalid
Error message
DACL is invalid
What it means
When setDACL is requested and a DACL is present, the library validates it with Advapi32.IsValidAcl. If the ACL structure fails Windows validation (bad AclRevision, size mismatch, corrupted ACEs), it throws IllegalArgumentException ('DACL is invalid').
Source
Thrown at contrib/platform/src/com/sun/jna/platform/win32/Advapi32Util.java:2893
throw new IllegalArgumentException("SECURITY_DESCRIPTOR_RELATIVE does not contain owner");
if (!Advapi32.INSTANCE.IsValidSid(psidOwner))
throw new IllegalArgumentException("Owner PSID is invalid");
infoType |= OWNER_SECURITY_INFORMATION;
}
if (setGroup) {
if (psidGroup == null)
throw new IllegalArgumentException("SECURITY_DESCRIPTOR_RELATIVE does not contain group");
if (!Advapi32.INSTANCE.IsValidSid(psidGroup))
throw new IllegalArgumentException("Group PSID is invalid");
infoType |= GROUP_SECURITY_INFORMATION;
}
if (setDACL) {
if (dacl == null)
throw new IllegalArgumentException("SECURITY_DESCRIPTOR_RELATIVE does not contain DACL");
if (!Advapi32.INSTANCE.IsValidAcl(dacl.getPointer()))
throw new IllegalArgumentException("DACL is invalid");
infoType |= DACL_SECURITY_INFORMATION;
}
if (setSACL) {
if (sacl == null)
throw new IllegalArgumentException("SECURITY_DESCRIPTOR_RELATIVE does not contain SACL");
if (!Advapi32.INSTANCE.IsValidAcl(sacl.getPointer()))
throw new IllegalArgumentException("SACL is invalid");
infoType |= SACL_SECURITY_INFORMATION;
}
/*
* Control bits SE_DACL_PROTECTED/SE_SACL_PROTECTED indicate the *ACL is protected. The *ACL_SECURITY_INFORMATION flags
* are meta flags for SetNamedSecurityInfo and are not stored in the SD. If either *ACLProtectedStatus is set,
* get the current status from the securityDescriptor and apply as such, otherwise the ACL remains at its default.
*/
if (setDACLProtectedStatus) {
if ((securityDescriptor.Control & SE_DACL_PROTECTED) != 0) {View on GitHub (pinned to d036ad9781)
Solutions
- Pre-check with Advapi32.INSTANCE.IsValidAcl(dacl.getPointer()) and rebuild the ACL if false.
- Rebuild the DACL with Advapi32Util.createAccessControlList or similar helper rather than hand-writing bytes.
- Re-extract the ACL from the source descriptor using the correct offsets (getSecurityDescriptorDacl).
- Skip the DACL component (setDACL=false) if invalid, then set it separately from a freshly built ACL.
Example fix
// before
Advapi32Util.setSecurityDescriptorComponents(sd, true, true, true, true, false, false);
// after
if (sd.getDiscretionaryACL() != null && Advapi32.INSTANCE.IsValidAcl(sd.getDiscretionaryACL().getPointer())) {
Advapi32Util.setSecurityDescriptorComponents(sd, true, true, true, true, false, false);
} Defensive patterns
Strategy: validation
Validate before calling
ACL dacl = securityDescriptor.getDiscretionaryACL();
if (dacl == null || !Advapi32.INSTANCE.IsValidAcl(dacl.getPointer())) {
throw new IllegalStateException("DACL missing or invalid");
} Type guard
boolean isValidDACL(SECURITY_DESCRIPTOR_RELATIVE sd) {
ACL a = sd.getDiscretionaryACL();
return a != null && Advapi32.INSTANCE.IsValidAcl(a.getPointer());
} Try / catch
try {
Advapi32Util.setSecurityDescriptorComponents(sd, false, false, true, false, false, false);
} catch (IllegalArgumentException e) {
log.error("DACL rejected: " + e.getMessage());
} Prevention
- Run Advapi32.INSTANCE.IsValidAcl on any ACL before applying it.
- Build ACLs with library helpers instead of hand-writing ACE bytes.
- Verify AclSize matches the actual buffer after manual construction.
When it happens
Trigger: setDACL=true where the ACL bytes are corrupted or inconsistent: declared AclSize not matching buffer, malformed ACEs, ACL built by hand with wrong header fields.
Common situations: Manually constructed ACL structures with incorrect ACE sizes; copying ACL memory between descriptors without fixing offsets; truncated descriptor buffers causing partial ACL reads.
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
- SACL is invalid
- SECURITY_DESCRIPTOR_RELATIVE does not contain owner
- Owner PSID is invalid
- SECURITY_DESCRIPTOR_RELATIVE does not contain group
- Group PSID is invalid
AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12).
Data as JSON: /api/errors/fbb9ef441469bdc1.
Report an issue: GitHub.