How to fix Error: FST_ERR_PLUGIN_ALREADY_REGISTERED: Plugin already registered in Node.js

Node.jsINTERMEDIATEHIGHUpdated Dec 9, 2025· 139 views

This error occurs when you attempt to register the same Fastify plugin multiple times, either directly in your code or through a chain of dependencies. Fastify prevents duplicate plugin registration to avoid conflicts, state duplication, and unpredictable behavior.

Quick fix

Fixes FST_ERR_PLUGIN_ALREADY_REGISTERED

const fastify = require('fastify')();

// The error will mention which of these plugins is registered twice
fastify.register(require('@fastify/cors'));
fastify.register(require('@fastify/jwt'));
fastify.register(require('./my-custom-plugin'));
  1. Identify which plugin is causing the duplicate registration
  2. Check for direct duplicate registrations in your code
  3. Check for indirect duplicates through imports
  4. Resolve dependency conflicts
node.js — error
const fastify = require('fastify')();
// The error will mention which of these plugins is registered twice
fastify.register(require('@fastify/cors'));
fastify.register(require('@fastify/jwt'));
fastify.register(require('./my-custom-plugin'));
Error: FST_ERR_PLUGIN_ALREADY_REGISTERED: Plugin already registered

What this error means

Fastify maintains an internal registry of all loaded plugins to ensure each plugin is initialized exactly once per Fastify instance. When you try to register a plugin that Fastify has already loaded, it throws this error to prevent duplicate initialization, which could cause: - State conflicts (plugins maintaining internal state would have duplicate instances) - Memory leaks (resources allocated by the first plugin instance not being cleaned up) - Unexpected behavior (hooks, routes, or decorators being registered twice) - Race conditions (plugins modifying shared state simultaneously) This is a safety mechanism, not a sign of the plugin itself being broken. The issue is in how the application is loading the plugin.

Typical symptoms

  • Error thrown during application startup with "FST_ERR_PLUGIN_ALREADY_REGISTERED" message
  • Application crashes immediately when starting the server
  • Server fails to listen on the specified port
  • Error trace shows the specific plugin name in the message
  • Error occurs only after recent dependency updates or plugin chain refactoring
  • Some plugins load successfully but one specific plugin causes the failure

Common causes

  1. Plugin is imported and registered multiple times in different files of your application
  2. Plugin is registered in both a parent route handler and a child route handler
  3. Plugin is accidentally registered in a middleware chain and also at the root level
  4. A dependency chain includes the same plugin multiple times (version conflicts)
  5. Plugin is registered both synchronously and asynchronously in the same app
  6. Using the same Fastify instance for multiple test suites without proper cleanup
  7. Plugin is loaded in a factory function that is called more than once per instance

How to fix "Error: FST_ERR_PLUGIN_ALREADY_REGISTERED: Plugin already registered"

1Identify which plugin is causing the duplicate registration

The error message should include the plugin name. Look at your Fastify initialization code to find where you register plugins:

javascript
const fastify = require('fastify')();

// The error will mention which of these plugins is registered twice
fastify.register(require('@fastify/cors'));
fastify.register(require('@fastify/jwt'));
fastify.register(require('./my-custom-plugin'));

If the error message is vague, add logging to see the exact sequence of plugin registrations:

javascript
fastify.addHook('onRegister', (instance, opts) => {
  console.log('Plugin registered:', opts);
});
2Check for direct duplicate registrations in your code

Search for the problematic plugin name across your project to find all registration points:

bash
# Search for plugin registration
grep -r "@fastify/cors" src/
grep -r "register(" src/

Each plugin should be registered exactly once. Example of what to avoid:

javascript
// ❌ Wrong - plugin registered twice
fastify.register(require('@fastify/cors'));
// ... more code ...
fastify.register(require('@fastify/cors')); // Duplicate!

// ✅ Correct - plugin registered once
fastify.register(require('@fastify/cors'));
3Check for indirect duplicates through imports

Sometimes the same plugin is registered through different module imports:

javascript
// app.js
const plugin = require('./my-plugin');
fastify.register(plugin);

// routes/api.js - imported by app.js
const plugin = require('./my-plugin');
fastify.register(plugin); // Same plugin, different import!

Move plugin registration to a single location and pass the fastify instance where needed:

javascript
// app.js - single registration
const plugin = require('./my-plugin');
fastify.register(plugin);

// routes/api.js - no plugin registration
module.exports = async (fastify) => {
  // Use plugin features without re-registering
  fastify.myDecorator(); // Plugin already loaded
};
4Resolve dependency conflicts

If the error appears after updating dependencies, it may be a transitive dependency issue. Check your package.json and dependency tree:

bash
# List all versions of a package in your dependency tree
npm list @fastify/cors

# Look for duplicates - should show only one version

If you see multiple versions, pin to a single version in package.json:

json
{
  "dependencies": {
    "@fastify/cors": "^8.0.0",
    "some-package": "^1.0.0"
  }
}

Then reinstall:

bash
rm -rf node_modules package-lock.json
npm install
5Ensure proper cleanup in tests

If this error occurs during testing, ensure you properly close the Fastify instance between tests:

javascript
// ❌ Wrong - fastify instance reused
let fastify;
beforeAll(() => {
  fastify = require('fastify')();
  fastify.register(require('@fastify/cors'));
});

afterEach(() => {
  // Not closing fastify!
});

test('test 1', () => {
  // fastify still has the plugin from test setup
});

Instead, create a fresh instance per test:

javascript
// ✅ Correct - fresh instance per test
beforeEach(async () => {
  fastify = require('fastify')();
  fastify.register(require('@fastify/cors'));
  await fastify.ready();
});

afterEach(async () => {
  await fastify.close();
});
6Use named routes to avoid plugin conflicts

If you're registering plugins in nested route contexts, use the prefix option to isolate them:

javascript
// Register plugin once at root level
fastify.register(async (instance) => {
  // All sub-routes inherit this plugin
  instance.decorateRequest('user', null);
});

// Bad - trying to re-register in a sub-route
fastify.register(async (instance) => {
  instance.register(require('@fastify/cors')); // OK here
  
  instance.register(async (subInstance) => {
    // Don't re-register parent plugins here
  });
});

// Good - use existing decorators in nested routes
fastify.register(async (parentInstance) => {
  parentInstance.register(require('@fastify/cors'));
  
  parentInstance.register(async (subInstance) => {
    // Decorators from parent are inherited
    subInstance.get('/', (req, res) => {
      // Can use req.user from parent plugin
    });
  });
});

Advanced notes

Plugin namespacing: Fastify uses the plugin function's name (or a custom namespace) to track registered plugins. If you're dynamically loading plugins, ensure unique identifiers:

javascript
const plugin = require('./my-plugin');
// Plugin will be tracked by its function.name property
fastify.register(plugin);

// If you want explicit control, pass a name in options:
fastify.register(plugin, { name: 'my-custom-name' });

Fastify context and scope: Each Fastify instance maintains its own plugin registry. If you're creating multiple Fastify instances, you can register the same plugin to each instance separately:

javascript
const fastify1 = require('fastify')();
const fastify2 = require('fastify')();

// Same plugin, different instances - no conflict
fastify1.register(require('@fastify/cors'));
fastify2.register(require('@fastify/cors'));

Plugin composition patterns: Modern Fastify applications often use composition patterns. Make sure you understand whether a helper function wraps plugin registration or is the plugin itself:

javascript
// This is a plugin factory - returns a plugin function
const createMyPlugin = (options) => {
  return async (fastify) => {
    // Actual plugin code
  };
};

// Register once, pass options if needed
fastify.register(createMyPlugin({ mode: 'strict' }));

Error stack trace analysis: The error stack trace will usually point to the exact line where the duplicate registration happened. Use --trace-warnings flag for more details:

bash
node --trace-warnings app.js

This helps identify whether the duplicate comes from your code or a dependency.

Frequently asked questions

What does "FST_ERR_PLUGIN_ALREADY_REGISTERED" mean?
Fastify maintains an internal registry of all loaded plugins to ensure each plugin is initialized exactly once per Fastify instance. When you try to register a plugin that Fastify has already loaded, it throws this error to prevent duplicate initialization, which could cause: - State conflicts (plugins maintaining internal state would have duplicate instances) - Memory leaks (resources allocated by the first plugin instance not being cleaned up) - Unexpected behavior (hooks, routes, or decorators being registered twice) - Race conditions (plugins modifying shared state simultaneously) This is a safety mechanism, not a sign of the plugin itself being broken. The issue is in how the application is loading the plugin.
How do I fix "FST_ERR_PLUGIN_ALREADY_REGISTERED"?
This error occurs when you attempt to register the same Fastify plugin multiple times, either directly in your code or through a chain of dependencies. Fastify prevents duplicate plugin registration to avoid conflicts, state duplication, and unpredictable behavior.
What causes "FST_ERR_PLUGIN_ALREADY_REGISTERED"?
Plugin is imported and registered multiple times in different files of your application Plugin is registered in both a parent route handler and a child route handler Plugin is accidentally registered in a middleware chain and also at the root level
Is the "FST_ERR_PLUGIN_ALREADY_REGISTERED" error serious?
Yes. This is a high-severity error that usually blocks work until it is fixed, but the steps above resolve it.

Official resources & further reading