fluent/fluentd · error · NotImplementedError
Implement this method in child class
Error message
Implement this method in child class
What it means
Fluent::Plugin::Storage is the abstract base class for storage plugins; #get is declared but only raises NotImplementedError to force subclasses to override it. Calling storage.get(key) means the storage object's class never provided a concrete getter. Fluentd's built-in LocalStorage and other shipped storages override it, so this error almost always means a custom storage plugin is incomplete or the base class was instantiated directly.
Source
Thrown at lib/fluent/plugin/storage.rb:62
def synchronized?
false
end
def implementation
self
end
def load
# load storage data from any data source, or initialize storage internally
end
def save
# save internal data store into data source (to be loaded)
end
def get(key)
raise NotImplementedError, "Implement this method in child class"
end
def fetch(key, defval)
raise NotImplementedError, "Implement this method in child class"
end
def put(key, value)
# return value
raise NotImplementedError, "Implement this method in child class"
end
def delete(key)
# return deleted value
raise NotImplementedError, "Implement this method in child class"
end
def update(key, &block) # transactional get-and-update
raise NotImplementedError, "Implement this method in child class"View on GitHub (pinned to dd45c6e18d)
Solutions
- Override #get(key) in your Fluent::Plugin::Storage subclass to return the value for the key from your backing store
- If you did not intend to write a storage plugin, use a built-in implementation such as the default 'local' type (Fluent::Plugin::LocalStorage) instead of the base class
- Cover the whole abstract API in your subclass: get, fetch, put, delete, and update (lines 61-81), plus load/save when persistence matters
- In tests, stub the abstract methods or use a test double derived from LocalStorage instead of the raw base class
Example fix
// before (custom storage plugin, incomplete)
class MyStorage < Fluent::Plugin::Storage
Fluent::Plugin.register_storage('my', self)
def put(key, value)
@data[key.to_s] = value
end
end
storage.get('counter') # => NotImplementedError
// after
class MyStorage < Fluent::Plugin::Storage
Fluent::Plugin.register_storage('my', self)
def put(key, value)
@data[key.to_s] = value
end
def get(key)
@data[key.to_s]
end
end Defensive patterns
Strategy: type-guard
Validate before calling
storage = Fluent::Plugin.new_storage('my')
raise 'storage does not implement #get' if storage.method(:get).owner == Fluent::Plugin::Storage Type guard
def concrete_storage?(storage)
%i[get fetch put delete update].all? do |m|
storage.respond_to?(m) && storage.method(m).owner != Fluent::Plugin::Storage
end
end Try / catch
begin
storage.get('key')
rescue NotImplementedError => e
logger.error("storage plugin is incomplete: #{e.message} (#{storage.class})")
raise
end Prevention
- When authoring a storage plugin, implement the full abstract API (get/fetch/put/delete/update) before registering it
- Add a unit test that calls every abstract method on your storage class so omissions surface in CI, not production
- Subclass Fluent::Plugin::LocalStorage and override only what differs, inheriting working CRUD defaults
- Run fluentd --dry-run against the config to exercise plugin configuration before deployment
When it happens
Trigger: Calling storage.get('some_key') on an instance of a class that inherits Fluent::Plugin::Storage without overriding #get (lib/fluent/plugin/storage.rb:61-63). Instantiating Fluent::Plugin::Storage itself via Fluent::Plugin.new_storage('...') with a type that maps to the base class, or writing a custom storage plugin (registered with Fluent::Plugin.register_storage) that omits #get.
Common situations: Writing a custom storage plugin (e.g. Redis- or memcached-backed) and forgetting one of the CRUD methods; test code that exercises a half-finished storage subclass; a plugin author who copied the skeleton but left #get as a stub before shipping.
Related errors
- Implement this method in child class
- key must be a string (or symbol for to_s)
- Optional API #parse_io is not implemented
- Optional API #parse_partial_data is not implemented
- Plugin @id or path for <storage> required when 'persistent'
AI-assisted analysis of fluent/fluentd@dd45c6e18d (2026-08-21).
Data as JSON: /api/errors/bfad1a1aad0704e2.
Report an issue: GitHub.