fluent/fluentd · error · Fluent::ConfigError

Plugin @id or path for <storage> required when 'persistent'

Error message

Plugin @id or path for <storage> required when 'persistent' is true

What it means

Fluent::Plugin::LocalStorage raises this Fluent::ConfigError during configure when persistent true is set but there is nowhere to persist: no explicit path was given, the owning plugin has no @id (so owner.plugin_root_dir is nil and no root_dir-based file can be derived), and no system root_dir applies. Persistent storage needs a deterministic file location across restarts, and without @id or path none exists, so configuration is rejected instead of silently losing state.

Source

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

            @multi_workers_available = false
          elsif File.exist?(@path) && File.directory?(@path)
            @path = File.join(@path, "worker#{fluentd_worker_id}", "storage.json")
            @multi_workers_available = true
          else # path file/directory doesn't exist
            if @path.end_with?('.json') # file
              @multi_workers_available = false
            else # directory
              @path = File.join(@path, "worker#{fluentd_worker_id}", "storage.json")
              @multi_workers_available = true
            end
          end
        elsif root_dir = owner.plugin_root_dir
          basename = (conf.arg && !conf.arg.empty?) ? "storage.#{conf.arg}.json" : "storage.json"
          @path = File.join(root_dir, basename)
          @multi_workers_available = true
        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 }

View on GitHub (pinned to dd45c6e18d)

Solutions

  1. Add a stable @id to the owning plugin, e.g. <filter app> @id my_counter </filter>, so the storage file is derived as <root_dir>/workerN/storage.json or storage.<arg>.json under the plugin's directory
  2. Set an explicit path in the storage section: <storage> persistent true path /var/log/fluent/my_state </storage>
  3. Set a system-wide root_dir in <system> (root_dir /var/log/fluent/state) so plugins with @id get deterministic storage paths
  4. If persistence is not actually required, set persistent false and accept the on-memory store (fluentd logs a warning about the on-memory fallback)

Example fix

# before
<filter app.**>
  @type record_counter
  <storage>
    persistent true
  </storage>
</filter>
# => Plugin @id or path for <storage> required when 'persistent' is true

# after
<filter app.**>
  @type record_counter
  @id app_record_counter
  <storage>
    persistent true
  </storage>
</filter>
Defensive patterns

Strategy: validation

Validate before calling

# dry-run the config before deploying; this error is raised at configure time
system('fluentd --dry-run -c /etc/fluent/fluent.conf') or raise 'fluentd config invalid'

Try / catch

begin
  agent.configure(conf)
rescue Fluent::ConfigError => e
  abort "config rejected: #{e.message}" # e.g. missing @id/path for persistent storage
end

Prevention

When it happens

Trigger: Config with <storage persistent true> (or @type local with persistent true) inside a plugin that has no @id and no path in the <storage> section, while <system> has no root_dir. For example <match ...> <storage> persistent true </storage> </match> with @id absent. Raised from LocalStorage#configure (storage_local.rb:69-70) during startup, so fluentd fails to boot the plugin.

Common situations: Enabling persistence for the saved-position of a tail-like plugin or a counting filter and forgetting that persistence anchors on plugin id; configs copied from examples that relied on a system-wide root_dir that is absent in the new deployment; running under a supervisor that strips plugin ids.

Related errors


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