puppetlabs/puppet · error · Puppet::Error
Can not create #{@resource.title}; parent directory does not
Error message
Can not create #{@resource.title}; parent directory does not exist What it means
ensure#check runs before syncing any creation (file, link, present). If File.dirname of the resource path does not exist, Puppet raises 'Can not create <title>; parent directory does not exist' — the same guard as the directory branch, applied to every ensure value that creates something.
Source
Thrown at lib/puppet/type/file/ensure.rb:152
should = source.checksum
else
should = property.should
end
if should == :absent
is = property.retrieve
else
is = :absent
end
property.change_to_s(is, should)
end
# Check that we can actually create anything
def check
basedir = File.dirname(@resource[:path])
if !Puppet::FileSystem.exist?(basedir)
raise Puppet::Error,
"Can not create #{@resource.title}; parent directory does not exist"
elsif !FileTest.directory?(basedir)
raise Puppet::Error,
"Can not create #{@resource.title}; #{dirname} is not a directory"
end
end
# We have to treat :present specially, because it works with any
# type of file.
def insync?(currentvalue)
unless currentvalue == :absent or resource.replace?
return true
end
if should == :present
!(currentvalue.nil? or currentvalue == :absent)
else
super(currentvalue)View on GitHub (pinned to e227c27540)
Solutions
- Declare and order the parent directory resource before the child (require/before/->).
- Create install roots in provisioning (package post-install, cloud-init, kickstart) or an early class.
- Run `puppet agent -t --debug` to see exactly which parent path is reported missing.
- For many nested files, manage the directory tree explicitly or use an ensure => directory root with source recursion.
Example fix
// before
file { '/opt/app/bin/tool':
ensure => file,
source => 'puppet:///modules/app/tool',
}
// after
file { '/opt/app/bin': ensure => directory }
->
file { '/opt/app/bin/tool':
ensure => file,
source => 'puppet:///modules/app/tool',
} Defensive patterns
Strategy: validation
Validate before calling
# Ruby pre-flight
basedir = File.dirname(resource_path)
fail("#{basedir} missing — provision it or add an ordered file resource") unless Puppet::FileSystem.exist?(basedir) Try / catch
rescue Puppet::Error; on /parent directory does not exist/ add the parent directory resource with a before/require relationship to the failing resource and re-run the agent.
Prevention
- Order parent creation before any child under it (require/before/->).
- Provision install roots in early classes or cloud-init.
- Watch fresh-node smoke tests — ordering bugs appear there first.
- Consider a directory root with source recursion for deep trees.
When it happens
Trigger: `file { '/opt/app/bin/tool': ensure => file, source => ... }` with /opt/app/bin absent; `ensure => link` under a nonexistent directory; `ensure => present` on a new nested path; parents managed later in the catalog without ordering.
Common situations: Fresh nodes where install directories are not provisioned yet; a module assuming a package creates the parent; purge workflows that removed the parent first; new modules applied before their prerequisite classes.
Related errors
- Cannot create #{@resource[:path]}; parent directory #{parent
- %{callee}: default expression for $%{from} tries to illegall
- Could not convert change %{name} to string: %{detail}
- No ability to determine if %{name} exists
- Could not back up; will not remove
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/b29bbca59dcf080b.
Report an issue: GitHub.