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

Failed to get volume information

Error message

Failed to get volume information

What it means

Raised by Security.supports_acl? (lib/puppet/util/windows/security.rb:176) when GetVolumeInformationW fails on the root of the given path. The method ascends the path to its volume root, appends a trailing backslash (required by the API), and queries the filesystem flags to test FILE_PERSISTENT_ACLS. Failure means the volume could not be queried at all: drive not ready (empty optical/removable drive), an unavailable network share, or a path whose root cannot be derived.

Source

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

  def get_group(path)
    return unless supports_acl?(path)

    get_security_descriptor(path).group
  end

  FILE_PERSISTENT_ACLS = 0x00000008

  def supports_acl?(path)
    supported = false
    root = Pathname.new(path).enum_for(:ascend).to_a.last.to_s
    # 'A trailing backslash is required'
    root = "#{root}\\" unless root =~ %r{[/\\]$}

    FFI::MemoryPointer.new(:pointer, 1) do |flags_ptr|
      if GetVolumeInformationW(wide_string(root), FFI::Pointer::NULL, 0,
                               FFI::Pointer::NULL, FFI::Pointer::NULL,
                               flags_ptr, FFI::Pointer::NULL, 0) == FFI::WIN32_FALSE
        raise Puppet::Util::Windows::Error, _("Failed to get volume information")
      end

      supported = flags_ptr.read_dword & FILE_PERSISTENT_ACLS == FILE_PERSISTENT_ACLS
    end

    supported
  end

  MASK_TO_MODE = {
    FILE::FILE_GENERIC_READ => S_IROTH,
    FILE::FILE_GENERIC_WRITE => S_IWOTH,
    (FILE::FILE_GENERIC_EXECUTE & ~FILE::FILE_READ_ATTRIBUTES) => S_IXOTH
  }

  def get_aces_for_path_by_sid(path, sid)
    get_security_descriptor(path).dacl.select { |ace| ace.sid == sid }
  end

View on GitHub (pinned to e227c27540)

Solutions

  1. Gate on reachability before ACL work: File.exist?/Dir.exist? on the path, and net use for shares.
  2. Rescue Puppet::Util::Windows::Error and treat an unqueryable volume as 'do not manage ACLs here' (return false), since transient media fail the query.
  3. Order resources so network volumes are validated or retried after network facts are up.
  4. Log e.code — 21 (ERROR_NOT_READY) and 53 (path/network not found) are the common transient codes.

Example fix

# before
supports = Security.supports_acl?(path)

# after — absent/transient volumes mean 'no ACL support'
supports = Dir.exist?(path) && begin
  Security.supports_acl?(path)
rescue Puppet::Util::Windows::Error
  false
end
Defensive patterns

Strategy: try-catch

Validate before calling

raise ArgumentError, "path not present: #{path}" unless File.exist?(path)
Security.supports_acl?(path)

Try / catch

begin
  ok = Security.supports_acl?(path)
rescue Puppet::Util::Windows::Error => e
  Puppet.debug "volume query failed for #{path} (#{e.code})"
  ok = false # unqueryable volume — do not manage ACLs
end

Prevention

When it happens

Trigger: Calling supports_acl? (directly or via Puppet file/ACL management) on an empty CD-ROM or unplugged removable drive (ERROR_NOT_READY 21); a UNC or mapped network path whose share is down (ERROR_BAD_NETPATH / path not found); a path supplied such that the derived root string is invalid.

Common situations: Agents managing files on removable or optical media; disconnected mapped drives at boot before the network is up; laptops with card readers; DFS shares temporarily unreachable.

Related errors


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