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

This version of Windows does not support symlinks. Windows

Error message

This version of Windows does not support symlinks.  Windows Vista / 2008 or higher is required.

What it means

Before any symlink operation, the Windows file-system layer calls raise_if_symlinks_unsupported: if Puppet.features.manages_symlinks? is false (the Puppet runtime lacks symlink support, classically Windows older than Vista/2008), it raises Puppet::Util::Windows::Error. Separately, if the user merely lacks the symlink privilege it only warns, so the raise is specifically about OS/runtime capability.

Source

Thrown at lib/puppet/file_system/windows.rb:217

      Puppet::Util::Windows::SID::BuiltinAdministrators,
      current_sid
    ].uniq.map do |sid|
      dacl.allow(sid, FULL_CONTROL)
    end
    dacl
  end

  def get_dacl_from_file(path)
    sd = Puppet::Util::Windows::Security.get_security_descriptor(path_string(path))
    sd.dacl
  rescue Puppet::Util::Windows::Error => e
    raise e unless e.code == FILE_NOT_FOUND
  end

  def raise_if_symlinks_unsupported
    unless Puppet.features.manages_symlinks?
      msg = _("This version of Windows does not support symlinks.  Windows Vista / 2008 or higher is required.")
      raise Puppet::Util::Windows::Error, msg
    end

    unless Puppet::Util::Windows::Process.process_privilege_symlink?
      Puppet.warning _("The current user does not have the necessary permission to manage symlinks.")
    end
  end
end

View on GitHub (pinned to e227c27540)

Solutions

  1. Run the agent on Windows Vista/Server 2008 or newer with a Puppet build that supports symlinks
  2. If upgrading the OS is not possible, avoid link resources on those nodes: use directory junctions via an exec, copy the target instead of linking, or condition resources on osfamily
  3. Note the separate 'current user does not have the necessary permission' message is only a warning (elevation/SeCreateSymbolicLinkPrivilege fixes it), not this error

Example fix

# before (manifest)
file { 'C:/opt/current': ensure => link, target => 'C:/opt/rel-1.2.3' }

# after (manifest, legacy Windows)
if $facts['os']['family'] == 'windows' and versioncmp($facts['os']['release']['major'], '6.0') < 0 {
  file { 'C:/opt/current': ensure => directory, source => 'puppet:///modules/app/rel-1.2.3', recurse => true }
} else {
  file { 'C:/opt/current': ensure => link, target => 'C:/opt/rel-1.2.3' }
}
Defensive patterns

Strategy: validation

Validate before calling

def symlink_capable?
  Puppet.features.manages_symlinks? && Puppet::Util::Windows::Process.process_privilege_symlink?
end

use_junction = Gem.win_platform? && !symlink_capable?

Type guard

# Feature guard usable in manifests
# $facts['os']['family'] == 'windows' and versioncmp($facts['os']['release']['major'], '6.0') >= 0

Try / catch

begin
  Puppet::FileSystem.link(target, link_path)
rescue Puppet::Util::Windows::Error => e
  raise unless e.message.include?('does not support symlinks')
  fallback_to_copy_or_junction
end

Prevention

When it happens

Trigger: Managing `ensure => link` file resources (or links => manage during recursive file serving) on a Windows host whose Ruby/Puppet build cannot create symlinks; running modern Puppet on legacy Windows (XP/2003) or a stripped runtime without symlink support.

Common situations: Legacy Windows fleets; unusual Ruby builds where the symlink functions are unavailable; modules assuming POSIX symlink semantics deployed to old Windows nodes.

Related errors


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