puppetlabs/puppet · error · Puppet::Util::Windows::Error

Failed to add access control entry

Error message

Failed to add access control entry

What it means

Raised when AddAccessAllowedAceEx returns FALSE inside Security.add_access_allowed_ace (lib/puppet/util/windows/security.rb:440). The SID has already passed IsValidSid at this point, so the failure is about the ACL itself: ERROR_ALLOTTED_SPACE_EXCEEDED (1344) when the ACL buffer has no room for another ACE (too many entries), ERROR_INVALID_PARAMETER (87) for inherit-flag combinations invalid at the pinned ACL_REVISION = 2, or ERROR_INVALID_ACL for a malformed or uninitialized ACL.

Source

Thrown at lib/puppet/util/windows/security.rb:440

    new_sd = Puppet::Util::Windows::SecurityDescriptor.new(sd.owner, sd.group, dacl, protected)
    set_security_descriptor(path, new_sd)

    nil
  end

  ACL_REVISION = 2

  def add_access_allowed_ace(acl, mask, sid, inherit = nil)
    inherit ||= NO_INHERITANCE

    Puppet::Util::Windows::SID.string_to_sid_ptr(sid) do |sid_ptr|
      if Puppet::Util::Windows::SID.IsValidSid(sid_ptr) == FFI::WIN32_FALSE
        raise Puppet::Util::Windows::Error, _("Invalid SID")
      end

      if AddAccessAllowedAceEx(acl, ACL_REVISION, inherit, mask, sid_ptr) == FFI::WIN32_FALSE
        raise Puppet::Util::Windows::Error, _("Failed to add access control entry")
      end
    end

    # ensure this method is void if it doesn't raise
    nil
  end

  def add_access_denied_ace(acl, mask, sid, inherit = nil)
    inherit ||= NO_INHERITANCE

    Puppet::Util::Windows::SID.string_to_sid_ptr(sid) do |sid_ptr|
      if Puppet::Util::Windows::SID.IsValidSid(sid_ptr) == FFI::WIN32_FALSE
        raise Puppet::Util::Windows::Error, _("Invalid SID")
      end

      if AddAccessDeniedAceEx(acl, ACL_REVISION, inherit, mask, sid_ptr) == FFI::WIN32_FALSE
        raise Puppet::Util::Windows::Error, _("Failed to add access control entry")
      end

View on GitHub (pinned to e227c27540)

Solutions

  1. Reduce the ACE count: grant a domain/local group and manage membership instead of enumerating accounts.
  2. Use inherit flags valid for the object type (CONTAINER_INHERIT_ACE|OBJECT_INHERIT_ACE for directories; none for plain files).
  3. Avoid object-type ACEs with this helper — it pins ACL_REVISION = 2, which cannot hold them.
  4. Rescue Puppet::Util::Windows::Error and log e.code to identify the limit hit (1344 buffer full vs 87 invalid parameter).

Example fix

# before — one ACE per user, ACL fills up
users.each { |u| add_access_allowed_ace(acl, mask, sid_for(u)) }

# after — one group, one ACE, inheritance flags set once
sid = Puppet::Util::Windows::SID.name_to_principal('DOMAIN\AppUsers')&.sid
inherit = 0x3 # CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE
add_access_allowed_ace(acl, mask, sid, inherit) if sid
Defensive patterns

Strategy: try-catch

Try / catch

begin
  add_access_allowed_ace(acl, mask, sid, inherit)
rescue Puppet::Util::Windows::Error => e
  Puppet.err "AddAccessAllowedAceEx failed (#{e.code}) for SID #{sid}"
  raise if e.code != 1344 # ERROR_ALLOTTED_SPACE_EXCEEDED
  # ACL full — collapse entries into a group and retry once
end

Prevention

When it happens

Trigger: Appending more ACEs than the ACL buffer was sized for (large permission lists); using object-inheritance flags that need ACL_REVISION_DS (3+) while the code pins revision 2; inherit flags not valid for the object type (files vs directories vs registry keys); an acl pointer that was not built by InitializeAcl.

Common situations: ACL resources granting many individual accounts on one object instead of groups; deep inheritance sets on directory trees and registry keys; DACLs approaching size limits after successive additions.

Related errors


AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21). Data as JSON: /api/errors/1a17685be3020acd. Report an issue: GitHub.