strapi/strapi · error · Error
Middleware ${uid} has already been registered.
Error message
Middleware ${uid} has already been registered. What it means
Thrown by `strapi.middleware.add(namespace, middlewares)` when a middleware name, once namespaced (via `addNamespace`), collides with an already-registered UID. Middlewares are stored in a map keyed by UID and the registry refuses to overwrite. The error fires during the per-key loop, so the first middleware in the batch that collides aborts the whole add.
Source
Thrown at packages/core/core/src/registries/middlewares.ts:50
/**
* Registers a middleware
*/
set(uid: UID.Middleware, middleware: Core.Middleware) {
middlewares[uid] = middleware;
return this;
},
/**
* Registers a map of middlewares for a specific namespace
*/
add(namespace: string, rawMiddlewares: Record<string, Core.Middleware> = {}) {
for (const middlewareName of Object.keys(rawMiddlewares)) {
const middleware = rawMiddlewares[middlewareName];
const uid = addNamespace(middlewareName, namespace) as UID.Middleware;
if (has(uid, middlewares)) {
throw new Error(`Middleware ${uid} has already been registered.`);
}
middlewares[uid] = middleware;
}
},
/**
* Wraps a middleware to extend it
*/
extend(uid: UID.Middleware, extendFn: MiddlewareExtendFn) {
const currentMiddleware = this.get(uid);
if (!currentMiddleware) {
throw new Error(`Middleware ${uid} doesn't exist`);
}
const newMiddleware = extendFn(currentMiddleware);
middlewares[uid] = newMiddleware;
View on GitHub (pinned to 4a4101264d)
Solutions
- Rename the conflicting middleware in `server/src/middlewares/<name>.ts` so its namespaced UID is unique.
- Restart the dev server cleanly if you suspect HMR double-registration.
- Confirm the plugin isn't loaded twice via `plugins.config.js` + `package.json` deps.
- If you intended to override, use `strapi.middleware('<uid>').extend(fn)` instead of `add()`.
Example fix
// before — collides with core cors middleware
module.exports = {
middlewares: { cors: { name: 'cors', handler: () => {} } },
};
// after — unique name, or use extend to override
strapi.middleware('plugin::myplugin.cors');
// or rename:
module.exports = {
middlewares: { myCors: { name: 'myCors', handler: () => {} } },
}; Defensive patterns
Strategy: validation
Validate before calling
function addMiddlewareSafely(strapi, namespace, middlewares) {
const existing = new Set(strapi.middleware.keys());
for (const name of Object.keys(middlewares)) {
const uid = `${namespace}::${name}`; // mirror addNamespace for known prefixes
if (existing.has(uid)) {
strapi.log.warn(`Skipping duplicate middleware ${uid}`);
continue;
}
}
strapi.middleware.add(namespace, middlewares);
} Type guard
const isMiddlewareRegistered = (strapi, uid: string): boolean => strapi.middleware.keys().includes(uid);
Try / catch
try {
strapi.middleware.add(namespace, middlewares);
} catch (e) {
if (!String(e.message).includes('has already been registered')) throw e;
} Prevention
- Use unique middleware names prefixed by your plugin.
- Don't load the same plugin twice (local + npm).
- Use `.extend()` to override an existing middleware rather than re-`add`.
When it happens
Trigger: Two plugins defining a middleware with the same name. A plugin re-declaring a middleware Strapi core already registered (e.g. `global::cors`, `plugin::users-permissions.jwt`). Hot-reload during `develop` re-running `add()` against a non-cleared registry.
Common situations: Plugin named `users-permissions` re-registering `jwt`. Local plugin loaded twice (npm package + local path). Hot-reload double-registration. Forking a plugin and forgetting to rename the middleware file.
Related errors
- Middleware ${uid} doesn't exist
- Module ${namespace} has already been registered.
- Plugin ${name} has already been registered.
- Policy ${uid} has already been registered.
- Service ${uid} has already been registered.
AI-assisted analysis of strapi/strapi@4a4101264d (2026-08-12).
Data as JSON: /api/errors/06e761f4da8247fb.
Report an issue: GitHub.