fluent/fluentd · warning · Fluent::Counter::UnknownKey

unknown_key

unknown_key

Error message

`#{key}` doesn't exist in counter

What it means

When fluentd starts, Supervisor#configure (lib/fluent/supervisor.rb:804) checks the --inline-config/-i option: the special value '-' means 'read the extra config directives from STDIN'. This usage is deprecated (fluentd issue #2711) because STDIN is not reliably available - Windows services, daemonized processes, and process supervisors detach or redirect stdin, so config silently comes back empty and startup breaks. The warning is emitted before Fluent::Config.build merges @inline_config as additional_config on top of the main config file.

Source

Thrown at lib/fluent/counter/store.rb:87

      def stop
        @storage.save
      end

      def init(key, data, ignore: false)
        ret = if v = get(key)
                raise InvalidParams.new("#{key} already exists in counter") unless ignore
                v
              else
                @storage.put(key, build_value(data))
              end

        build_response(ret)
      end

      def get(key, raise_error: false, raw: false)
        ret = if raise_error
                @storage.get(key) or raise UnknownKey.new("`#{key}` doesn't exist in counter")
              else
                @storage.get(key)
              end
        if raw
          ret
        else
          ret && build_response(ret)
        end
      end

      def key?(key)
        !!@storage.get(key)
      end

      def delete(key)
        ret = @storage.delete(key) or raise UnknownKey.new("`#{key}` doesn't exist in counter")
        build_response(ret)
      end

View on GitHub (pinned to dd45c6e18d)

Solutions

  1. Stop piping config via stdin: concatenate the snippets into a real file and start with it, e.g. `cat fluent.conf extra.conf > merged.conf && fluentd -c merged.conf`.
  2. Pass the inline config text directly in the option value instead of '-', e.g. `fluentd -c fluent.conf -i '<match **>@type null</match>'`.
  3. If you really need stdin for the whole config, use `fluentd -c /dev/stdin < full.conf` (on Unix-like systems) instead of `-i -`.
  4. Remove any '-' default for inline_config in wrapper scripts/service definitions (td-agent.conf / systemd unit / NSSM arguments).

Example fix

# before
fluentd -c fluent.conf -i - < extra.conf

# after
cat fluent.conf extra.conf > /tmp/merged.conf && fluentd -c /tmp/merged.conf
Defensive patterns

Strategy: validation

Validate before calling

# launcher script: reject the deprecated stdin form before invoking fluentd
if printf '%s\n' "$@" | grep -qE '(^|[ =])(-i|--inline-config)(=|-)$'; then
  echo "ERROR: inline_config '-' is deprecated; use -c <file> or pass config text to -i" >&2
  exit 1
fi
exec fluentd "$@"

Type guard

def fluentd_inline_config?(value)
  value.is_a?(String) && !value.strip.empty? && value.strip != '-'
end

raise ArgumentError, "inline_config '-' is deprecated (fluentd#2711)" unless fluentd_inline_config?(inline_config)

Try / catch

# Not an exception - it is a $log.warn during configure; nothing to rescue.
# Guard at the process boundary instead: detect '-' before launch and fail fast with a clear message.

Prevention

When it happens

Trigger: Starting fluentd with `-i -` (or `--inline-config -`, or `--inline-config=-`) and piping config text on stdin, e.g. `fluentd -c fluent.conf -i - < extra.conf`. Any wrapper/launcher that sets inline_config to the literal string '-' hits the branch at supervisor.rb:804-807.

Common situations: Legacy deployment scripts or CI pipelines that pipe an extra config snippet into fluentd; migrating a setup to td-agent running as a Windows service (where stdin is detached and STDIN.read returns nothing); container init scripts that worked with old fluentd versions.

Related errors


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