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

Failed to initialize ACL

Error message

Failed to initialize ACL

What it means

Raised by set_security_descriptor when InitializeAcl fails on the freshly allocated ACL buffer sized by get_max_generic_acl_size. InitializeAcl only fails when the buffer is too small for the ACL header (below ~8 bytes, e.g. a degenerate allocation) or the revision is wrong, so in this code path it signals an allocation/sizing problem rather than anything about the target file.

Source

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

    sd
  end

  def get_max_generic_acl_size(ace_count)
    # https://msdn.microsoft.com/en-us/library/windows/desktop/aa378853(v=vs.85).aspx
    # To calculate the initial size of an ACL, add the following together, and then align the result to the nearest DWORD:
    # * Size of the ACL structure.
    # * Size of each ACE structure that the ACL is to contain minus the SidStart member (DWORD) of the ACE.
    # * Length of the SID that each ACE is to contain.
    ACL.size + ace_count * MAXIMUM_GENERIC_ACE_SIZE
  end

  # setting DACL requires both READ_CONTROL and WRITE_DACL access rights,
  # and their respective privileges, SE_BACKUP_NAME and SE_RESTORE_NAME.
  def set_security_descriptor(path, sd)
    FFI::MemoryPointer.new(:byte, get_max_generic_acl_size(sd.dacl.count)) do |acl_ptr|
      if InitializeAcl(acl_ptr, acl_ptr.size, ACL_REVISION) == FFI::WIN32_FALSE
        raise Puppet::Util::Windows::Error, _("Failed to initialize ACL")
      end

      if IsValidAcl(acl_ptr) == FFI::WIN32_FALSE
        raise Puppet::Util::Windows::Error, _("Invalid DACL")
      end

      with_privilege(SE_BACKUP_NAME) do
        with_privilege(SE_RESTORE_NAME) do
          open_file(path, READ_CONTROL | WRITE_DAC | WRITE_OWNER) do |handle|
            Puppet::Util::Windows::SID.string_to_sid_ptr(sd.owner) do |owner_sid_ptr|
              Puppet::Util::Windows::SID.string_to_sid_ptr(sd.group) do |group_sid_ptr|
                sd.dacl.each do |ace|
                  case ace.type
                  when Puppet::Util::Windows::AccessControlEntry::ACCESS_ALLOWED_ACE_TYPE
                    # puts "ace: allow, sid #{Puppet::Util::Windows::SID.sid_to_name(ace.sid)}, mask 0x#{ace.mask.to_s(16)}"
                    add_access_allowed_ace(acl_ptr, ace.mask, ace.sid, ace.flags)
                  when Puppet::Util::Windows::AccessControlEntry::ACCESS_DENIED_ACE_TYPE
                    # puts "ace: deny, sid #{Puppet::Util::Windows::SID.sid_to_name(ace.sid)}, mask 0x#{ace.mask.to_s(16)}"

View on GitHub (pinned to e227c27540)

Solutions

  1. Check the appended Win32 text / e.code for the concrete reason
  2. Verify the DACL being applied has a sane, non-negative ACE count
  3. Reproduce with the same Ruby/FFI versions; mismatched ffi gem struct layouts can corrupt sizes
  4. Reduce ACL size applied to the resource and retry
Defensive patterns

Strategy: try-catch

Try / catch

begin
  Puppet::Util::Windows::Security.set_security_descriptor(path, sd)
rescue Puppet::Util::Windows::Error => e
  raise unless e.message.include?('Failed to initialize ACL')
  raise Puppet::Error, "ACL init failed (code #{e.code}); check Ruby/ffi compatibility and ACE count #{sd.dacl.count}"
end

Prevention

When it happens

Trigger: set_security_descriptor where get_max_generic_acl_size(sd.dacl.count) computes a size smaller than the minimum ACL header (only conceivable with a broken ace_count) or FFI memory allocation returned a bad buffer; ACL_REVISION mismatch on the running Windows version.

Common situations: Almost never seen in practice; occasionally reported after memory pressure or FFI binding issues on unusual Ruby builds (e.g. 32-bit/64-bit struct layout mismatches).

Related errors


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