puppetlabs/puppet · error · Puppet::Error
%{klass} could not write %{path}: %{detail}
Error message
%{klass} could not write %{path}: %{detail} What it means
The write twin of FileType's read decorator: exceptions from the filetype-specific write that are not already Puppet::Error (permission denied, read-only filesystem, ENOSPC) are logged and re-raised as Puppet::Error '%{klass} could not write %{path}: %{detail}'. The cache is only marked synced (@synced = Time.now) when the write succeeds.
Source
Thrown at lib/puppet/util/filetype.rb:66
raise
rescue => detail
message = _("%{klass} could not read %{path}: %{detail}") % { klass: self.class, path: @path, detail: detail }
Puppet.log_exception(detail, message)
raise Puppet::Error, message, detail.backtrace
end
# And then the write method
define_method(:real_write, instance_method(:write))
define_method(:write) do |text|
val = real_write(text)
@synced = Time.now
val
rescue Puppet::Error
raise
rescue => detail
message = _("%{klass} could not write %{path}: %{detail}") % { klass: self.class, path: @path, detail: detail }
Puppet.log_exception(detail, message)
raise Puppet::Error, message, detail.backtrace
end
end
end
def self.filetype(type)
@filetypes[type]
end
# Pick or create a filebucket to use.
def bucket
@bucket ||= Puppet::Type.type(:filebucket).mkdefaultbucket.bucket
end
def initialize(path, default_mode = nil)
raise ArgumentError, _("Path is nil") if path.nil?
@path = path
@default_mode = default_modeView on GitHub (pinned to e227c27540)
Solutions
- Verify write permission and filesystem mutability for the agent user (ls -l, lsattr)
- Ensure the parent directory exists and the file is not immutable
- Rescue Puppet::Error at the call site, report it, and remediate (permissions/mount) before retrying
Example fix
# before
Puppet::Util::FileType.filetype(:flat).new('/etc/motd').write(text)
# => Puppet::Error: ... could not write /etc/motd: Read-only file system
# after
begin
Puppet::Util::FileType.filetype(:flat).new('/etc/motd').write(text)
rescue Puppet::Error => e
Puppet.err("motd not updated: #{e.message}")
end Defensive patterns
Strategy: try-catch
Validate before calling
writable = File.exist?(path) ? File.writable?(path) : File.writable?(File.dirname(path))
raise ArgumentError, "#{path} not writable" unless writable
ft.write(text) Try / catch
begin
ft.write(text)
rescue Puppet::Error => e
Puppet.err("write failed: #{e.message}")
raise unless e.message =~ /Resource temporarily unavailable/
end Prevention
- Check File.writable? on the file or its parent directory before writing
- Avoid chattr +i and read-only mounts on managed paths
- Rescue Puppet::Error around writes; the original cause is embedded in the message
When it happens
Trigger: Puppet::Util::FileType.filetype(:flat).new('/etc/app.conf').write(text) as a user without write permission, on a read-only mount, or when the target's parent directory is missing; crontab writes failing through the cron binary hit the same wrapper.
Common situations: Agents running least-privilege but managing root-owned files, immutable/append-only files (chattr +i), containers with read-only /etc, and full disks.
Related errors
- %{klass} could not read %{path}: %{detail}
- puppet.plans/invalid-name
- Could not back up %{file}: %{detail}
- %{path} is not readable
- Could not destroy %{json} %{request}: %{detail}
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/494b6fb1405ab8e0.
Report an issue: GitHub.