fluent/fluentd · critical · Fluent::InvalidRootDirectory
failed to create root directory:#{root_dir}, #{e.inspect}
Error message
failed to create root directory:#{root_dir}, #{e.inspect} What it means
Fluentd raises Fluent::InvalidRootDirectory during startup when the <system> root_dir path does not exist and FileUtils.mkdir_p fails to create it (lib/fluent/supervisor.rb:719). The nested e.inspect in the message carries the underlying filesystem error, such as Errno::EACCES or Errno::ENOSPC. This happens before any plugin starts, so the whole fluentd process aborts during configuration/boot.
Source
Thrown at lib/fluent/supervisor.rb:719
if @system_config.workers < 1
raise Fluent::ConfigError, "invalid number of workers (must be > 0):#{@system_config.workers}"
end
if Fluent.windows? && @system_config.with_source_only
raise Fluent::ConfigError, "with-source-only is not supported on Windows"
end
root_dir = @system_config.root_dir
if root_dir
if File.exist?(root_dir)
unless Dir.exist?(root_dir)
raise Fluent::InvalidRootDirectory, "non directory entry exists:#{root_dir}"
end
else
begin
FileUtils.mkdir_p(root_dir, mode: @system_config.dir_permission || Fluent::DEFAULT_DIR_PERMISSION)
rescue => e
raise Fluent::InvalidRootDirectory, "failed to create root directory:#{root_dir}, #{e.inspect}"
end
end
end
begin
ServerEngine::Privilege.change(@chuser, @chgroup)
MessagePackFactory.init(enable_time_support: @system_config.enable_msgpack_time_support)
Fluent::Engine.init(@system_config, supervisor_mode: true, start_in_parallel: ENV.key?("FLUENT_RUNNING_IN_PARALLEL_WITH_OLD"))
Fluent::Engine.run_configure(@conf, dry_run: dry_run)
rescue Fluent::ConfigError => e
$log.error 'config error', file: @config_path, error: e
$log.debug_backtrace
exit!(1)
rescue ScriptError => e # LoadError, NotImplementedError, SyntaxError
if e.respond_to?(:path)
$log.error e.message, path: e.path, error: e
else
$log.error e.message, error: eView on GitHub (pinned to dd45c6e18d)
Solutions
- Check the underlying error in the message (e.inspect) — Errno::EACCES means permissions, Errno::ENOSPC means disk full
- If permission denied: chown or chmod the parent directory so the fluentd user can create it (e.g. install -d -o fluent -g fluent /var/log/fluent)
- If running in a container, ensure the volume mounted at root_dir is writable by the container user (fsGroup / runAsUser in Kubernetes, or chown in an entrypoint)
- Pre-create the directory yourself before starting fluentd so mkdir_p is never called
- For SELinux denials, set the correct context (restorecon) or adjust the policy for the fluentd process
Example fix
# before <system> root_dir /var/log/fluent/buffer # owned by root, fluentd runs as 'fluent' </system> # after (option 1: pre-create with correct ownership) # sudo install -d -o fluent -g fluent /var/log/fluent/buffer # after (option 2: point root_dir somewhere writable) <system> root_dir /home/fluent/spool </system>
Defensive patterns
Strategy: validation
Validate before calling
require 'fileutils'
root_dir = '/var/log/fluent'
# pre-flight check mirroring supervisor.rb logic
if File.exist?(root_dir)
abort "#{root_dir} exists but is not a directory" unless Dir.exist?(root_dir)
else
begin
FileUtils.mkdir_p(root_dir)
rescue => e
abort "cannot create #{root_dir}: #{e.class} #{e.message} — check permissions/disk"
end
end
# also verify writability of the final directory
abort "#{root_dir} not writable" unless File.writable?(root_dir) Prevention
- Pre-create root_dir with correct ownership in your provisioning (install -d -o fluent -g fluent)
- In containers, chown the volume in the entrypoint or set Kubernetes fsGroup to match the fluentd user
- Monitor disk free space and inodes on the root_dir filesystem
- Run fluentd --dry-run after config changes to fail before production restart
When it happens
Trigger: Setting <system> root_dir /path/to/dir where the parent path is not writable by the fluentd user, the disk or inode quota is exhausted, a symlink in the path is broken, or the path crosses a read-only mount. Also triggered when root_dir points somewhere SELinux denies creation for the fluentd process context.
Common situations: Running fluentd as a low-privileged user while root_dir points under /var/log/fluent or a Docker volume owned by root; deploying to Kubernetes with an emptyDir/volumeMount whose ownership does not match the container UID; SELinux/AppArmor denying writes; full disk filling /tmp.
Related errors
- Plugin storage path '#{@path}' is not readable/writable
- Directory is not writable for plugin storage file '#{@path}'
- Cannot access pid file: #{pid_path}
- Cannot access directory for pid file: #{File.dirname(pid_pat
- out_secondary_file: `#{@directory}` should be writable
AI-assisted analysis of fluent/fluentd@dd45c6e18d (2026-08-21).
Data as JSON: /api/errors/4fef8f103da79a67.
Report an issue: GitHub.