fluent/fluentd · error · Fluent::ConfigError

Directory is not writable for plugin storage file '#{@path}'

Error message

Directory is not writable for plugin storage file '#{@path}'

What it means

When the storage file does not yet exist, LocalStorage#configure creates its parent directory with FileUtils.mkdir_p and then requires that directory to be writable (File.stat(dir).writable?, storage_local.rb:100); if it is not, this Fluent::ConfigError aborts configuration. Fluentd needs to create the file on first save, so an unwritable parent directory makes persistence impossible and the misconfiguration is reported at startup rather than at first save.

Source

Thrown at lib/fluent/plugin/storage_local.rb:100

        if !@on_memory
          dir = File.dirname(@path)
          FileUtils.mkdir_p(dir, mode: @dir_mode) unless Dir.exist?(dir)
          if File.exist?(@path)
            raise Fluent::ConfigError, "Plugin storage path '#{@path}' is not readable/writable" unless File.readable?(@path) && File.writable?(@path)
            begin
              data = File.open(@path, 'r:utf-8:utf-8') { |io| io.read }
              if data.empty?
                log.warn "detect empty plugin storage file during startup. Ignored: #{@path}"
                return
              end
              data = JSON.parse(data, Fluent::DEFAULT_JSON_PARSE_OPTIONS)
              raise Fluent::ConfigError, "Invalid contents (not object) in plugin storage file: '#{@path}'" unless data.is_a?(Hash)
            rescue => e
              log.error "failed to read data from plugin storage file", path: @path, error: e
              raise Fluent::ConfigError, "Unexpected error: failed to read data from plugin storage file: '#{@path}'"
            end
          else
            raise Fluent::ConfigError, "Directory is not writable for plugin storage file '#{@path}'" unless File.stat(dir).writable?
          end
        end
      end

      def multi_workers_ready?
        unless @multi_workers_available
          log.error "local plugin storage with multi workers should be configured to use directory 'path', or system root_dir and plugin id"
        end
        @multi_workers_available
      end

      def load
        return if @on_memory
        return unless File.exist?(@path)
        begin
          json_string = File.open(@path, 'r:utf-8:utf-8'){ |io| io.read }
          json = JSON.parse(json_string, Fluent::DEFAULT_JSON_PARSE_OPTIONS)
          unless json.is_a?(Hash)

View on GitHub (pinned to dd45c6e18d)

Solutions

  1. Make the parent directory writable by the fluentd user: chown fluent:fluent /var/log/fluent && chmod 0755 /var/log/fluent
  2. Point path at a location the runtime user can write, such as /var/log/fluent/ or a dedicated state directory
  3. In containers, ensure the state path is a writable volume mount (and not on the read-only image layer)
  4. Check for SELinux/AppArmor denials if classic permissions look correct (audit.log or ausearch -m avc)

Example fix

# before
$ ls -ld /var/lib/fluent
 drwxr-xr-x 2 root root 4096 /var/lib/fluent
# fluentd runs as 'fluent' => Directory is not writable for plugin storage file

# after
$ sudo chown -R fluent:fluent /var/lib/fluent
$ sudo chmod 0755 /var/lib/fluent
Defensive patterns

Strategy: validation

Validate before calling

dir = File.dirname('/var/log/fluent/storage.json')
FileUtils.mkdir_p(dir) unless Dir.exist?(dir)
raise "directory #{dir} not writable" unless File.stat(dir).writable?

Try / catch

begin
  plugin.configure(conf)
rescue Fluent::ConfigError => e
  if e.message.include?('Directory is not writable for plugin storage file')
    warn 'chown/chmod the storage directory or move path to a writable volume'; exit 1
  end
  raise
end

Prevention

When it happens

Trigger: path (or the root_dir/@id-derived directory) points into a directory owned by root or another user while fluentd runs unprivileged; directory mode 0555 or on a read-only filesystem; SELinux denial on the state directory; typo'd path resolving to a protected location like /etc or /.

Common situations: First run of a persistent-storage plugin after adding @id without pre-creating the state directory; switching the service to a non-root user without chown-ing the parent dir; read-only root filesystems in containers where the state dir was not mounted writable.

Related errors


AI-assisted analysis of fluent/fluentd@dd45c6e18d (2026-08-21). Data as JSON: /api/errors/a74364d835b25708. Report an issue: GitHub.