fluent/fluentd · error · Fluent::ConfigError

Plugin storage path '#{@path}' is not readable/writable

Error message

Plugin storage path '#{@path}' is not readable/writable

What it means

During LocalStorage#configure (storage_local.rb:86), if the resolved storage file already exists but the fluentd process cannot both read and write it (File.readable? or File.writable? false), configuration fails with this Fluent::ConfigError. LocalStorage rewrites the whole JSON file on every save, so read-only or non-writable state files cannot be honored; the error usually indicates an ownership mismatch between the file and the user running fluentd.

Source

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

        else
          if @persistent
            raise Fluent::ConfigError, "Plugin @id or path for <storage> required when 'persistent' is true"
          else
            if @autosave
              log.warn "both of Plugin @id and path for <storage> are not specified. Using on-memory store."
            else
              log.info "both of Plugin @id and path for <storage> are not specified. Using on-memory store."
            end
            @on_memory = true
            @multi_workers_available = true
          end
        end

        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

View on GitHub (pinned to dd45c6e18d)

Solutions

  1. Fix ownership of the storage file to the fluentd runtime user: chown fluent:fluent /path/to/storage.json (and its directory)
  2. Ensure the mode allows owner read/write: chmod 0600 or 0644 owned by the running user
  3. If the permissions are intentional (read-only snapshot), move or delete the stale file so LocalStorage recreates it — but note saved state will be lost
  4. When running under systemd/Docker, verify User=, ReadOnlyPaths=, or volume mount options are not making the file unwritable

Example fix

# before
$ ls -l /var/log/fluent/storage.json
-rw------- 1 root root 1024 ... storage.json
# fluentd (as user 'fluent') fails:
# Plugin storage path '...' is not readable/writable

# after
$ sudo chown fluent:fluent /var/log/fluent/storage.json
$ sudo chmod 0600 /var/log/fluent/storage.json
Defensive patterns

Strategy: validation

Validate before calling

path = '/var/log/fluent/storage.json'
if File.exist?(path) && !(File.readable?(path) && File.writable?(path))
  raise \"storage file #{path} not readable/writable by #{Process.uid}\"
end

Try / catch

begin
  plugin.configure(conf)
rescue Fluent::ConfigError => e
  if e.message.include?('not readable/writable')
    warn 'Fix ownership of the storage file and restart'; exit 1
  end
  raise
end

Prevention

When it happens

Trigger: An existing storage.json (or path-specified storage file) owned by root while fluentd runs as the fluent user; a file with mode 0644 owned by another user so File.writable? is false; state files restored from backup with restrictive permissions (e.g. rsync -a preserving root ownership) and then reused at startup.

Common situations: Switching fluentd from root to a non-root service user after state files were created; Docker images where state paths were volume-mounted with wrong ownership; SELinux or read-only mounts making an existing file unwritable; files created by a different worker id layout during a multi-worker migration.

Related errors


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