puppetlabs/puppet · error · Puppet::Error
Will not remove directory backup %{newfile}; use a filebucke
Error message
Will not remove directory backup %{newfile}; use a filebucket What it means
Puppet's file resource makes local backups by copying the managed path to path + backup suffix (default 'puppet.bak') before replacing it. Before writing the new backup, perform_backup_with_backuplocal calls remove_backup to unlink the previous one. If the backup target exists and its ftype is 'directory', remove_backup raises Puppet::Error at lib/puppet/util/backups.rb:69 because Puppet refuses to recursively delete a whole directory tree just to rotate a backup; the message points at filebuckets as the supported alternative for backing up directories.
Source
Thrown at lib/puppet/util/backups.rb:69
self.fail Puppet::Error, _("Could not back %{file} up: %{message}") % { file: file, message: detail.message }, detail
end
end
def remove_backup(newfile)
if instance_of?(Puppet::Type::File) and self[:links] != :follow
method = :lstat
else
method = :stat
end
begin
stat = Puppet::FileSystem.send(method, newfile)
rescue Errno::ENOENT
return
end
if stat.ftype == "directory"
raise Puppet::Error, _("Will not remove directory backup %{newfile}; use a filebucket") % { newfile: newfile }
end
info _("Removing old backup of type %{file_type}") % { file_type: stat.ftype }
begin
Puppet::FileSystem.unlink(newfile)
rescue => detail
message = _("Could not remove old backup: %{detail}") % { detail: detail }
log_exception(detail, message)
self.fail Puppet::Error, message, detail
end
end
def backup_file_with_filebucket(f)
sum = bucket.backup(f)
info _("Filebucketed %{f} to %{filebucket} with sum %{sum}") % { f: f, filebucket: bucket.name, sum: sum }
sum
endView on GitHub (pinned to e227c27540)
Solutions
- Remove or rename the directory at {path}{backup} (e.g. `rm -rf /etc/motd.puppet.bak`) so the next Puppet run can recreate a regular file backup
- Switch the resource to filebucket backup: declare a `filebucket { 'main': server => ... }` resource and set the file's `backup` parameter to the bucket name, which is what the error message recommends
- Set `backup => false` on the file resource if no backup is needed at all
- Audit other file resources on the node for the same backup-target collision before the next agent run
Example fix
# before
file { '/etc/motd':
ensure => file,
source => 'puppet:///modules/motd/motd',
backup => '.bak', # fails when /etc/motd.bak is a directory
}
# after
filebucket { 'main':
server => 'puppet.example.com',
}
file { '/etc/motd':
ensure => file,
source => 'puppet:///modules/motd/motd',
backup => 'main', # filebucket handles directories safely
} Defensive patterns
Strategy: validation
Validate before calling
# Before letting Puppet manage the file, verify the local backup target is not a directory
path = '/etc/motd'
suffix = '.puppet.bak' # or the resource's backup parameter
backup_target = path + suffix
if File.exist?(backup_target) && File.ftype(backup_target) == 'directory'
abort "Refusing to run: #{backup_target} is a directory; Puppet would fail with 'Will not remove directory backup'. Remove it or use a filebucket."
end Try / catch
# In Ruby code driving Puppet (e.g. rake tasks, orchestration), fail gracefully instead of letting the agent run abort:
begin
# apply the catalog / run the resource
rescue Puppet::Error => e
if e.message.include?('Will not remove directory backup')
target = e.message[/Will not remove directory backup ([^;]+);/, 1]
warn "Backup target #{target} is a directory - remove it or switch the resource to a filebucket"
else
raise
end
end Prevention
- Prefer filebucket backups (backup => <bucket name>) over local suffix backups on servers where directories may share the name space
- Never create directories whose name equals path + backup suffix of a managed file
- Set backup => false on file resources that do not need backups to shrink the failure surface
- In CI for manifests, lint for local backup suffixes on file resources that manage directories
When it happens
Trigger: A file resource with a local backup suffix (backup => '.bak' or the default) whose target path+backup already exists as a directory on the node: someone ran `mkdir /etc/motd.puppet.bak`, a previous run used FileUtils.cp_r (which copies directories too, see backups.rb:46) and left a directory backup that the next run now refuses to remove, or a restore/rename left a directory at exactly that name.
Common situations: Converging a node where an operator manually created a directory with the backup name; a resource that changed between file and directory content while keeping local suffix backups; leftovers from an interrupted or older-format run; path prefixes chosen so path+backup collides with an unrelated directory.
Related errors
- Could not back up %{file}: %{detail}
- Could not back up; will not remove
- Unable to verify existing FileBucket backup at '%{path}'.
- Need exactly two arguments: filebucket diff <file_a> <file_b
- Diff is not supported on this platform
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/25be60e5e7fdc08a.
Report an issue: GitHub.