puppetlabs/puppet · error · Puppet::Error
Cannot create #{@resource[:path]}; parent directory #{parent
Error message
Cannot create #{@resource[:path]}; parent directory #{parent} does not exist What it means
The ensure property's :directory value creates the target with Dir.mkdir, which (unlike `mkdir -p`) cannot create intermediate directories. Puppet guards this explicitly: if File.dirname of the resource path does not exist it raises 'Cannot create <path>; parent directory <parent> does not exist' instead of surfacing Errno::ENOENT.
Source
Thrown at lib/puppet/type/file/ensure.rb:86
property.sync
else
@resource.write
@resource.should(:mode)
end
end
# aliasvalue(:present, :file)
newvalue(:present, :event => :file_created) do
# Make a file if they want something, but this will match almost
# anything.
set_file
end
newvalue(:directory, :event => :directory_created) do
mode = @resource.should(:mode)
parent = File.dirname(@resource[:path])
unless Puppet::FileSystem.exist? parent
raise Puppet::Error,
"Cannot create #{@resource[:path]}; parent directory #{parent} does not exist"
end
if mode
Puppet::Util.withumask(0o00) do
Dir.mkdir(@resource[:path], symbolic_mode_to_int(mode, 0o755, true))
end
else
Dir.mkdir(@resource[:path])
end
@resource.send(:property_fix)
return :directory_created
end
newvalue(:link, :event => :link_created, :required_features => :manages_symlinks) do
property = resource.property(:target)
fail "Cannot create a symlink without a target" unless property
property.retrieveView on GitHub (pinned to e227c27540)
Solutions
- Declare each parent and order it: `file { '/data/app': ensure => directory } -> file { '/data/app/logs': ensure => directory }`.
- Add `require => File['/data/app']` on the child (or `before` on the parent).
- For deep trees, generate one resource per level with a defined type.
- Re-read the reported parent path for typos — a misspelled segment looks identical to a missing one.
Example fix
// before
file { '/data/app/logs': ensure => directory }
// after: create and order each parent
file { '/data': ensure => directory }
file { '/data/app': ensure => directory }
->
file { '/data/app/logs': ensure => directory } Defensive patterns
Strategy: validation
Validate before calling
# Ruby pre-flight
parent = File.dirname(target_path)
unless Puppet::FileSystem.exist?(parent)
fail("#{parent} does not exist — declare file { '#{parent}': ensure => directory } and order it first")
end Try / catch
rescue Puppet::Error; on /parent directory .* does not exist/ add the missing parent as an ordered file resource and re-run — the catalog converges incrementally, no manual cleanup needed.
Prevention
- Declare every path level and chain with -> arrows.
- Never assume mkdir -p semantics.
- Test manifests with rspec-puppet against a fresh tmpdir.
- Re-check the reported parent path for typos.
When it happens
Trigger: `file { '/data/app/logs': ensure => directory }` when /data/app does not exist yet; the parent resource exists in the catalog but is ordered after the child (missing require/before/->); a typo in one path segment; parents present on some nodes but not others.
Common situations: Assuming recursive mkdir -p semantics; fresh nodes missing mount points or install roots; ordering bugs where the parent directory resource lacks a relationship arrow; modules assuming a package created the parent.
Related errors
- Can not create #{@resource.title}; parent directory does not
- %{callee}: default expression for $%{from} tries to illegall
- Could not back up; will not remove
- Could not read #{ftype} #{resource.title}: #{detail}
- Can not create #{@resource.title}; #{dirname} is not a direc
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/76fa984c047e0480.
Report an issue: GitHub.