ipfs/kubo · error

already have a datastore named %q

Error message

already have a datastore named %q

What it means

fsrepo keeps a global registry (datastores map[string]ConfigFromMap) mapping datastore type names to config constructors. AddDatastoreConfigHandler registers a new one and returns this error when a constructor is already registered under the same name. It guards against duplicate plugin registration and collisions with built-in datastore types (flatfs, badgerds, etc.).

Source

Thrown at repo/fsrepo/datastores.go:69

func (spec DiskSpec) String() string {
	return string(spec.Bytes())
}

var datastores map[string]ConfigFromMap

func init() {
	datastores = map[string]ConfigFromMap{
		"mount":   MountDatastoreConfig,
		"mem":     MemDatastoreConfig,
		"log":     LogDatastoreConfig,
		"measure": MeasureDatastoreConfig,
	}
}

func AddDatastoreConfigHandler(name string, dsc ConfigFromMap) error {
	_, ok := datastores[name]
	if ok {
		return fmt.Errorf("already have a datastore named %q", name)
	}

	datastores[name] = dsc
	return nil
}

// AnyDatastoreConfig returns a DatastoreConfig from a spec based on
// the "type" parameter.
func AnyDatastoreConfig(params map[string]any) (DatastoreConfig, error) {
	which, ok := params["type"].(string)
	if !ok {
		return nil, fmt.Errorf("'type' field missing or not a string")
	}
	fun, ok := datastores[which]
	if !ok {
		return nil, fmt.Errorf("unknown datastore type: %s", which)
	}
	return fun(params)

View on GitHub (pinned to 329838acdf)

Solutions

  1. Rename the plugin's datastore to a unique name (prefix it, e.g. "myorg-flatfs") and rebuild the plugin
  2. Remove the duplicate plugin file from the plugins directory so only one registration happens
  3. Ensure the plugin loader / AddDatastoreConfigHandler is invoked once per process (guard with sync.Once or init-time check)
  4. If intentionally overriding, unregister or extend the registry first — but avoid shadowing built-in datastore names

Example fix

// before
func init() {
    plugin.RegisterDatastore("flatfs", NewFlatfsConfig) // already have a datastore named "flatfs"
}
// after
func init() {
    plugin.RegisterDatastore("example-flatfs", NewFlatfsConfig) // unique name
}
Defensive patterns

Strategy: validation

Validate before calling

func canRegister(name string) bool {
    _, exists := registeredDatastores[name]
    return !exists
}
if !canRegister("example-flatfs") {
    return fmt.Errorf("datastore name already taken; choose another")
}

Try / catch

if err := AddDatastoreConfigHandler(name, ctor); err != nil {
    if strings.HasPrefix(err.Error(), "already have a datastore named") {
        log.Printf("skipping duplicate datastore registration for %s", name)
        return nil // idempotent registration
    }
    return err
}

Prevention

When it happens

Trigger: A datastore plugin calling AddDatastoreConfigHandler with a name already taken: loading two plugins that register the same datastore name, restarting/double-initializing the plugin loader in one process (loadDatastorePlugins run twice), or a plugin choosing a name identical to a built-in ("flatfs", "badgerds").

Common situations: Users installing a third-party datastore plugin that conflicts with another installed plugin or a built-in name; plugin directories containing duplicate/symlinked copies of the same plugin; kubo used as a library where makeNode or plugin injection runs more than once per process.

Related errors


AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03). Data as JSON: /api/errors/3b3330d4ea25f973. Report an issue: GitHub.