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.

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)

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.