java-native-access/jna · error · IllegalArgumentException

Owner PSID is invalid

Error message

Owner PSID is invalid

What it means

In the same security-descriptor update path, after confirming an owner SID exists, Advapi32Util calls Advapi32.IsValidSid to verify the SID structure. If Windows reports the owner PSID is not a valid SID, the library throws IllegalArgumentException instead of letting the Win32 call fail later with an opaque error.

Solutions

  1. Validate the SID yourself with Advapi32.INSTANCE.IsValidSid(psidOwner) before the call and repair/re-read it if false.
  2. Re-parse the SECURITY_DESCRIPTOR_RELATIVE from the full, unmodified descriptor bytes so owner offsets land correctly.
  3. Use Advapi32Util.convertSidBinaryToString / getTokenOwner-style helpers to round-trip the SID and confirm it is well formed.
  4. Fetch a fresh owner SID from a reliable source (e.g. LookupAccountName) instead of reusing hand-built bytes.

Example fix

// before
Advapi32Util.setSecurityDescriptorComponents(sd, true, true, true, true, false, false);
// after
if (Advapi32.INSTANCE.IsValidSid(sd.getOwner())) {
    Advapi32Util.setSecurityDescriptorComponents(sd, true, true, true, true, false, false);
}
Defensive patterns

Strategy: validation

Validate before calling

if (securityDescriptor.getOwner() == null || !Advapi32.INSTANCE.IsValidSid(securityDescriptor.getOwner())) {
    throw new IllegalStateException("Owner SID missing or invalid");
}

Type guard

boolean isValidOwner(SECURITY_DESCRIPTOR_RELATIVE sd) {
    return sd.getOwner() != null && Advapi32.INSTANCE.IsValidSid(sd.getOwner());
}

Try / catch

try {
    Advapi32Util.setSecurityDescriptorComponents(sd, true, false, false, false, false, false);
} catch (IllegalArgumentException e) {
    log.error("Owner SID rejected: " + e.getMessage());
}

Prevention

When it happens

Trigger: Calling with setOwner=true where psidOwner is non-null but its bytes are malformed: wrong revision, bad sub-authority count, SID buffer smaller than declared, or a SID copied from memory at the wrong offset.

Common situations: Hand-assembling SIDs or copying them out of a raw byte buffer with an incorrect offset/length; parsing a descriptor with mismatched offsets; truncating a descriptor before parsing so the owner SID references memory past the buffer.

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


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

Appendix: source

Thrown at contrib/platform/src/com/sun/jna/platform/win32/Advapi32Util.java:2877

                                                      boolean setOwner,
                                                      boolean setGroup,
                                                      boolean setDACL,
                                                      boolean setSACL,
                                                      boolean setDACLProtectedStatus,
                                                      boolean setSACLProtectedStatus) {

        final PSID psidOwner = securityDescriptor.getOwner();
        final PSID psidGroup = securityDescriptor.getGroup();
        final ACL dacl = securityDescriptor.getDiscretionaryACL();
        final ACL sacl = securityDescriptor.getSystemACL();

        int infoType = 0;
        // Parameter validation and infoType flag setting.
        if (setOwner) {
            if (psidOwner == null)
                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;
        }

View on GitHub (pinned to d036ad9781)