puppetlabs/puppet · error · Puppet::Error
Can not create #{@resource.title}; #{dirname} is not a direc
Error message
Can not create #{@resource.title}; #{dirname} is not a directory What it means
Second branch of ensure#check: the parent path exists but FileTest.directory? is false — a regular file, device, or file-symlink occupies the dirname slot, so no child can be created beneath it and Puppet raises '<title>; <dirname> is not a directory'.
Source
Thrown at lib/puppet/type/file/ensure.rb:155
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)
end
end
View on GitHub (pinned to e227c27540)
Solutions
- Inspect the parent: `ls -ld <dirname>` to identify the conflicting object.
- If it is a stray file, remove it (or manage its removal with a file resource) so the directory can be created.
- Manage the parent explicitly as ensure => directory so Puppet converges it before children.
- Fix the manifest if the child path was meant to nest elsewhere.
Example fix
// before: /etc/app/conf.d is a regular file on disk
file { '/etc/app/conf.d/routes.conf':
ensure => file,
source => 'puppet:///modules/app/routes.conf',
}
// after: converge the parent first (remove the stray file once)
file { '/etc/app/conf.d': ensure => directory }
->
file { '/etc/app/conf.d/routes.conf':
ensure => file,
source => 'puppet:///modules/app/routes.conf',
} Defensive patterns
Strategy: validation
Validate before calling
# Ruby pre-flight
parent = File.dirname(path)
if File.exist?(parent) && !File.directory?(parent)
fail("#{parent} exists but is a #{File.ftype(parent)}, not a directory — remove or relocate it")
end Try / catch
rescue Puppet::Error; on /is not a directory/ lstat the parent path, remove or relocate the conflicting object (or manage it as ensure => absent), then re-run the agent.
Prevention
- Check ls -ld on the parent before introducing nested resources.
- Avoid reusing a path for both a file and a directory role across releases.
- Watch for placeholder files committed into image builds.
- Manage parents explicitly as ensure => directory.
When it happens
Trigger: `file { '/etc/app/conf.d/routes.conf': ensure => file }` when /etc/app/conf.d is a plain file; a symlink pointing at a file sitting at the parent path; container images or packages shipping a placeholder file where a directory is expected.
Common situations: Name collisions between a file and a needed directory (committed placeholder files); broken symlinks from relocated software; manifests switching a path's role from file to directory without removing the old object.
Related errors
- The output directory '%{outputdir}' exists and is not a dire
- Could not destroy %{json} %{request}: %{detail}
- Could not read JSON data for %{name} %{key}: %{detail}
- Could not destroy %{name} %{request}: %{detail}
- The environment directory '%{env_dir}' does not exist
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/d0a13a037c71ab22.
Report an issue: GitHub.