@nestjs/microservices
12.2.0 · 19 Oct 2026MIT1.2M / weekRepositoryHomepagenpmAtom feed
392 stable releases, newest first, by release line. Notes are quoted as the maintainers published them.
- 12.x · latest line
12.2.0
19 Oct 2026@Sse({ maxPendingDataLength })sets how many characters of event data may wait for a client that is not reading its events (4M by default;0orInfinitylifts the limit) – 2f05ad954eIoAdapterandWsAdaptertakemaxConcurrentMessages, the number of a client's messages handled at once (1000 by default;Infinitylifts it) – 0bd0810ed7ValidationPipetakesmaxErrorMessagesLength(1,000,000 characters by default); messages past it are replaced by a "Further validation errors were omitted" entry – 086c1c514f
Notable changes
New options
@Sse({ maxPendingDataLength })sets how many characters of event data may wait for a client that is not reading its events (4M by default;0orInfinitylifts the limit) – 2f05ad954eIoAdapterandWsAdaptertakemaxConcurrentMessages, the number of a client's messages handled at once (1000 by default;Infinitylifts it) – 0bd0810ed7ValidationPipetakesmaxErrorMessagesLength(1,000,000 characters by default); messages past it are replaced by a "Further validation errors were omitted" entry – 086c1c514fKafka:
parser.maxMessageSize(16 MiB after decompression by default); larger messages are logged and skipped – 9bdf844fcaTCP server:
drainTimeout(30 s by default,0disables) disconnects a peer that leaves its responses unread – 583d6077adMQTT server:
reconnectOnConnackErroris now enabled by default, so a refused connection attempt is retried; set it tofalsefor the previous behaviour – a63cea600aHttpServer.getRouteMatchingOptions(), an optional adapter hook that tells core how the router matches paths (see "Middleware exclusions" below) – 08d8677c8d
New defaults and behaviour changes
@nestjs/platform-express,@nestjs/platform-fastify:fieldNestingDepthandfieldArrayIndexLimit(#18074) now default to 32 and 1000; set them toInfinityto lift the limits – 94fcc93770ValidationPipevalidates withvalidationError.target: falseunless the options set it, so anexceptionFactorythat readserror.targetgetsundefined; setvalidationError.targettotruefor the old errors – 8c5a59bf63ValidationPipeanswers an array or a primitive sent for a validated class with a 400 – 197371c1f3FileTypeValidatormatches a stringfileTypeup to the end of a name (e.g.font/woffno longer acceptsfont/woff2; use a RegExp for that) – 770c6f1a19@SerializeOptions({})on a handler no longer turns off the class schema – d27cb7017fBaseExceptionFilteranswershttp-errorserrors created withexpose: false(the default from 500) with the standard reason phrase instead of their message – 9ed572f853A
StreamableFileerror still gets a 400, but the body no longer carries the error message – 2f28d91afbFiles uploaded with a request that a pipe rejected are removed from storage – acb98de89e
@nestjs/platform-fastify: a route withfileSize: undefined(ornull) falls back to the plugin's limit; set it toInfinityto keep uploads unlimited – dd549e1a74@nestjs/platform-express: object error bodies are sent asapplication/jsonon routes with a non-JSONContent-Type– 7dc6e349d5ConsoleLoggerin JSON mode cuts a record short past about a million characters – ad4915eaa3A global enhancer that the injector failed to instantiate now fails the application at startup – ae78524ced
A request- or transient-scoped
APP_FILTERnow logs a startup warning, as it only applies to exceptions thrown from controllers – df5275c5e1Microservices: a pattern key longer than 256 characters matches no handler – accd27e66c
Kafka: a message may carry up to 10,000 header values (e419ff540b); headers given as a string or array are not sent (312777743f); reply headers are decoded as text
gRPC: request streams are paused while their replies wait to be written – 37e5cf7706
Deprecation: on TCP, Redis, NATS, MQTT and RabbitMQ, an
@EventPattern()handler that replies toClientProxy#send()now logs a deprecation warning. The reply is unchanged; in the next major version event handlers will not reply tosend(), as on Kafka already – ba3668d36b
Middleware exclusions
MiddlewareConsumer.exclude()now compiles excluded routes with the router's case and trailing-slash matching (08d8677c8d). Update@nestjs/coretogether with@nestjs/platform-express/@nestjs/platform-fastify: with an adapter that does not implementgetRouteMatchingOptions(), excluded routes are matched exactly (f5aa875e40), so on a lenient router other spellings of an excluded path run the middleware.With header, media type or custom versioning,
exclude({ path, method, version })andenableCsrfProtection({ exclude })apply only to requests that ask for one of the excluded versions – 1a7a31fa46@nestjs/platform-fastify: the request hook used byenableCsrfProtection()anduseSecurityHeaders()now runs before Nest andapp.use()middleware withNestFactory.create()too, including middleware registered before either call, as it already did withTest.createNestApplication()– 8351806290
Bug fixes
platform-fastifyfix(fastify): send the status of an exception whose body is an error (@kamilmysliwiec)
fix(fastify): apply middleware to plugins registered before init (@kamilmysliwiec)
fix(fastify): keep raw-response cookies in the header helpers (@johnnyhuirilef)
fix(fastify): match middleware paths like a case-insensitive router (@kamilmysliwiec)
fix(fastify): pass version extractor errors to the error handler (@kamilmysliwiec)
fix(fastify): pass middleware rejections to the error handler (@kamilmysliwiec)
fix(fastify): stop reading a streamable file for a head request (@kamilmysliwiec)
fix(fastify): let undefined upload limits fall back to the defaults (@kamilmysliwiec)
fix(fastify): free memory storage chunks once a file is buffered (@kamilmysliwiec)
fix(fastify): remove uploads cut off after their last chunk (@kamilmysliwiec)
fix(fastify): set the security headers on router error responses (@kamilmysliwiec)
fix(fastify): answer request targets that are not a path with 404 (@kamilmysliwiec)
fix(fastify): apply route options to all-method routes (@Ahmad-Mosha)
microservicesfix(microservices): handle malformed kafka reply assigner member metadata (@SssiiiSssii1)
fix(microservices): leave the init hooks to the hybrid application (@kamilmysliwiec)
fix(microservices): call the init hooks once when init() is called (@kamilmysliwiec)
fix(microservices): preserve request order during deferred replay (@Benziza)
fix(microservices): limit the number of kafka header values (@kamilmysliwiec)
fix(microservices): send no kafka headers given as a string or array (@kamilmysliwiec)
fix(microservices): decode kafka reply headers as text (@kamilmysliwiec)
fix(microservices): limit the size of kafka messages the parser decodes (@kamilmysliwiec)
fix(microservices): pause grpc request streams while replies wait (@kamilmysliwiec)
fix(microservices): end grpc unary subscriptions with the call (@kamilmysliwiec)
fix(microservices): fail grpc calls whose handler promise rejects (@kamilmysliwiec)
fix(microservices): fail grpc response streams that emit null (@kamilmysliwiec)
fix(microservices): send grpc errors that grpc-js can encode (@kamilmysliwiec)
fix(microservices): error grpc duplex calls on upstream error (@kamilmysliwiec)
fix(microservices): route mqtt messages by the topic they arrived on (@kamilmysliwiec)
fix(microservices): validate request ids before echoing them (@kamilmysliwiec)
fix(microservices): drain streamed replies in linear time (@kamilmysliwiec)
fix(microservices): limit the length of pattern keys (@kamilmysliwiec)
fix(microservices): drop rmq replies that amqp cannot address (@kamilmysliwiec)
fix(microservices): only emit rmq replies that a request waits for (@kamilmysliwiec)
fix(microservices): reject mqtt topics longer than 65535 bytes (@kamilmysliwiec)
fix(microservices): count mqtt requests that wait for the subscription (@kamilmysliwiec)
fix(microservices): drop idle reply channels from subscription counts (@kamilmysliwiec)
fix(microservices): use unguessable request ids and nats reply inboxes (@kamilmysliwiec)
fix(microservices): emit plain rpc filter results once on stream errors (@kamilmysliwiec)
fix(microservices): honor falsy results of rpc exception filters (@kamilmysliwiec)
fix(microservices): keep reconnecting the mqtt server after a refusal (@kamilmysliwiec)
fix(microservices): flatten async rpc filter results on stream errors (@kamilmysliwiec)
fix(microservices): stop tcp observable responses when the peer leaves (@kamilmysliwiec)
fix(microservices): reply to a request only from its message handler (@kamilmysliwiec)
fix(microservices): drop tcp peers that stop reading their responses (@kamilmysliwiec)
fix(microservices): use the right filters for inherited scoped handlers (@kamilmysliwiec)
fix(microservices): keep sibling event handlers running on error (@kamilmysliwiec)
fix(microservices): drop the mqtt client when a reconnect is refused (@kamilmysliwiec)
fix(microservices): reject tcp data too long to be a content length (@kamilmysliwiec)
fix(microservices): consume again after the rmq consumer is cancelled (@kamilmysliwiec)
fix(microservices): close tls connections still in their handshake (@kamilmysliwiec)
fix(microservices): close rmq server connection when channel close fails (@kamilmysliwiec)
fix(microservices): run other event handlers when a scoped one fails (@OmBhandwaldar)
fix(microservices): keep reading tcp replies during client backpressure (@maxymlyskov)
fix(microservices): close the rmq channel before the connection (@maxymlyskov)
fix(microservices): ignore a redis server's own replies under wildcards (@maxymlyskov)
fix(microservices): match empty mqtt topic levels (@ys0v9)
corefix(core): run interceptor, pipe and filter classes without a name (@kamilmysliwiec)
fix(core): detect cycles in request-scoped forward references (@DevAhmadAlkhuja)
fix(core): give a module that extends another module its own id (@maxymlyskov)
fix(core): answer http requests an rpc exception filter leaves (@kamilmysliwiec)
fix(core): settle async param decorator values before pipes run (@kamilmysliwiec)
fix(core): subscribe to guard observables from other copies of rxjs (@kamilmysliwiec)
fix(core): run guards bound as classes without a name (@kamilmysliwiec)
fix(core): find the module of a host registered under another token (@kamilmysliwiec)
fix(core): run middleware on a controller root excluded by a wildcard (@kamilmysliwiec)
fix(core): stop wildcard exclusions from covering their parent route (@kamilmysliwiec)
fix(core): mount middleware paths on routes excluded from the prefix (@kamilmysliwiec)
fix(core): drop an overlapped middleware route only when it is covered (@kamilmysliwiec)
fix(core): mount unversioned middleware paths under the default version (@kamilmysliwiec)
fix(core): map controller middleware under every module declaring it (@kamilmysliwiec)
fix(core): mount transient-scoped middleware instead of skipping it (@kamilmysliwiec)
fix(core): never exclude request targets with "#" or in absolute form (@kamilmysliwiec)
fix(core): hide internal error messages from sse error events (@kamilmysliwiec)
fix(core): drop sse clients that stop reading their events (@kamilmysliwiec)
fix(core): hand sse header errors to the exception filters (@kamilmysliwiec)
fix(core): leave early sse errors to the exception filters (@kamilmysliwiec)
fix(core): trim only spaces and tabs around cookie names and values (@kamilmysliwiec)
fix(core): wait for the redirect reply before settling the route (@kamilmysliwiec)
fix(core): stop reusing durable instances holding a failed placeholder (@kamilmysliwiec)
fix(core): run transient global enhancers on static entry providers (@kamilmysliwiec)
fix(core): fail at startup when a global enhancer is not instantiated (@kamilmysliwiec)
fix(core): await deferred loads of forward-referenced providers (@kamilmysliwiec)
fix(core): inject every property of overlapping first resolutions (@kamilmysliwiec)
fix(core): keep the root inquirer of transient providers per resolution (@kamilmysliwiec)
fix(core): apply the enhancers of class providers under any token (@kamilmysliwiec)
fix(core): recompute scope flags cached inside a circular dependency (@kamilmysliwiec)
fix(core): run enhancers that are request-scoped through dependencies (@kamilmysliwiec)
fix(core): destroy a
StreamableFilethat is not sent (@kamilmysliwiec)fix(core): destroy a
StreamableFiledropped by a timed-out handler (@kamilmysliwiec)fix(core): warn that scoped global filters miss non-controller errors (@kamilmysliwiec)
fix(core): do not send the message of an unexposed http error (@kamilmysliwiec)
fix(core): answer host mismatches on fastify with 404 (@kamilmysliwiec)
fix(core): use the right filters for inherited request-scoped middleware (@kamilmysliwiec)
fix(core): keep exact routes ahead of optional groups by specificity (@kamilmysliwiec)
fix(core): end sse responses to head requests once headers are sent (@kamilmysliwiec)
fix(core): use the right filters for inherited request-scoped routes (@kamilmysliwiec)
fix(core): honor falsy results of filters in external contexts (@kamilmysliwiec)
fix(core): treat fastify validation errors as http errors (@OmBhandwaldar)
fix(core): reject create() when a dependency is request-scoped (@maxymlyskov)
fix(core): release the throwaway wrapper of each create() call (@maxymlyskov)
fix(core): keep route options when the route triggered hook is set (@OmBhandwaldar)
commonfix(common): match a file type string up to the end of a name (@kamilmysliwiec)
fix(common): stop exposing the validated object on validation errors (@kamilmysliwiec)
fix(common): limit the length of validation error messages by default (@kamilmysliwiec)
fix(common): stop copying nested validation errors for each level (@kamilmysliwiec)
fix(common): reject arrays and primitives for validated classes (@kamilmysliwiec)
fix(common): validate parsed array items one at a time (@kamilmysliwiec)
fix(common): keep
StreamableFileerror messages out of responses (@kamilmysliwiec)fix(common): handle
StreamableFileerrors raised before the reply (@kamilmysliwiec)fix(common): keep the class schema when a handler sets serialize options (@kamilmysliwiec)
fix(common): keep the loaded transformer while serializers are created (@kamilmysliwiec)
fix(common): strip a falsy constructor key from request data (@kamilmysliwiec)
fix(common): cut json log records short past a million characters (@kamilmysliwiec)
fix(common): traverse a shared object once in the logger redactor (@kamilmysliwiec)
fix(common): keep custom decorator options followed by a pipe (@kamilmysliwiec)
fix(common): copy array and object defaults in
DefaultValuePipe(@kamilmysliwiec)fix(common): skip array holes when stripping prototype keys (@kamilmysliwiec)
fix(common): avoid mutating input arrays during validation (@dcavalcante)
fix(common): call
stringifyReplacerwith the logger asthis(@Chaoqi31)fix(common): detect stacks whose error message spans several lines (@Chaoqi31)
fix(common): parse
error()calls with a lone or an undefined stack (@Chaoqi31)
platform-express,platform-fastifyfix(express,fastify): parse quoted media type version parameters (@li-jia-nan)
fix(express,fastify): handle a
StreamableFilethat cannot be streamed (@kamilmysliwiec)fix(express,fastify): let a route's dest replace the module's storage (@kamilmysliwiec)
fix(express,fastify): limit field nesting and array indexes by default (@kamilmysliwiec)
testingfix(testing): share one auto-mock between providers of the same token (@jayhemnani9910)
fix(testing): resolve auto-mocked dependencies of transient providers (@jayhemnani9910)
core,microservicesfix(core,microservices): let only the hybrid application bind gateways (@kamilmysliwiec)
websocketsfix(websockets): await deferred loads of a gateway's scoped enhancers (@kamilmysliwiec)
fix(websockets): create the filters of a gateway that failed to resolve (@kamilmysliwiec)
fix(websockets): resolve hook error filters in the connection's context (@kamilmysliwiec)
fix(websockets): use the right filters for inherited gateway handlers (@kamilmysliwiec)
fix(websockets): log and reply when the error cause cannot be sent (@kamilmysliwiec)
core,websocketsfix(core,websockets): run transient enhancers bound to static gateways (@kamilmysliwiec)
fix(core): key the handler metadata cache by class, not class name (@maxymlyskov)
common,corefix(core,common): exclude a version only for requests that ask for it (@kamilmysliwiec)
fix(core): make the sse pending data limit configurable (@kamilmysliwiec)
fix(core): match excluded routes exactly when the router is unknown (@kamilmysliwiec)
core,platform-expressfix(core): mount wildcard middleware on every path when "/" is excluded (@kamilmysliwiec)
platform-expressfix(express): run wildcard middleware on "/api/" for a named wildcard (@kamilmysliwiec)
fix(express): stop reading a streamable file for a head request (@kamilmysliwiec)
fix(express): send object error bodies with a json content type (@kamilmysliwiec)
platform-ws,websocketsfix(ws): stop reading from a client that does not read its replies (@kamilmysliwiec)
fix(ws): drop messages from a client the server is closing (@kamilmysliwiec)
platform-socket.io,platform-ws,websocketsfix(websockets): bound how many messages of a client are handled at once (@kamilmysliwiec)
core,microservices,websocketsfix(core,microservices,websockets): ignore inherited keys of non-objects (@kamilmysliwiec)
fix(core): read class-level enhancers from the registered class (@kamilmysliwiec)
platform-wsfix(ws): listen on the host of a gateway with its own port and a path (@kamilmysliwiec)
fix(ws): answer non-upgrade requests on a gateway's own port with 426 (@kamilmysliwiec)
fix(ws): close the socket of an upgrade request it cannot parse (@kamilmysliwiec)
core,platform-express,platform-fastifyfix(core,express,fastify): remove uploads of requests a pipe rejected (@kamilmysliwiec)
core,testingfix(core): fail at bootstrap on missing deps of scoped providers (@kamilmysliwiec)
fix(testing): mock dependencies of request-scoped providers (@johnnyhuirilef)
common,platform-fastifyfix(fastify): run the security request hook ahead of middie (@kamilmysliwiec)
common,core,platform-express,platform-fastifyfix(core,express,fastify): match excluded routes like the router does (@kamilmysliwiec)
common,core,microservices,platform-express,platform-fastify,platform-socket.io,platform-ws,testing,websocketsfix: expose package.json in the exports map of all packages (@minijus)
Enhancements
microservicesfeat(microservices): deprecate event handlers replying to send() (@kamilmysliwiec)
coreperf(core): resolve route params without a promise when no pipe runs (@thekhegay)
perf(core): avoid AsyncResource.bind() per request in the interceptor chain (@thekhegay)
Committers: 15
Ahmed Gamal (@Ahmad-Mosha)
Chaoqi (@Chaoqi31)
Daniel Cavalcante (@dcavalcante)
Jay Hemnani (@jayhemnani9910)
Johnny J. Huirilef Millán (@johnnyhuirilef)
Kamil Mysliwiec (@kamilmysliwiec)
Maksym Lyskov (@maxymlyskov)
Minijus L (@minijus)
Mohamed A. Abdel Fattah (@SssiiiSssii1)
Om Bhandwaldar (@OmBhandwaldar)
Roman Khegay (@thekhegay)
Sua Choi (@ys0v9)
lijianan (@li-jia-nan)
12.1.3
12 Oct 2026core,microservicesplatform-expresscore
Bug fixes
core,microservicesfix(core,microservices): flush buffered logs when initialization fails (@thekhegay)
fix(core,microservices): run transient global enhancers on controllers (@johnnyhuirilef)
platform-expressfix(express): guard async request hook completion (@GiHoon1123)
fix(express): destroy the
StreamableFilesource on client disconnect (@maxymlyskov)fix(express): run wildcard middleware on the bare global prefix path (@Chaoqi31)
corefix(core): fail at startup for request-scoped class global enhancers (@thekhegay)
fix(core): stop silently dropping request-scoped global enhancers (@OmBhandwaldar)
fix(core): resolve uri versioned exclusions for the not-found handler (@basteez)
fix(core): normalize slashes when mapping controllers for middleware (@basteez)
fix(core): do not mutate the message when assigning an sse event id (@Metehan-Bicer)
fix(core): end sse streams whose event data cannot be serialized (@OmBhandwaldar)
fix(core): send status and headers set by handlers on sse responses (@johnnyhuirilef)
fix(core): honor a shutdown signal received while close() is in flight (@maxymlyskov)
fix(core): settle SSE lifecycle on early disconnect (@jackie-cqz)
fix(core): commit SSE headers for empty streams (@jackie-cqz)
fix(core): preserve explicit null values in reflectable decorators (@gophersg)
fix(core): run the shutdown sequence after a failed init (@kamilmysliwiec)
fix(core): send the expires header on sse responses (@Mohamed-Elshesheny)
fix(core): honor global prefix exclusions for overlapping versions (@Chaoqi31)
fix(core): let a
GETmiddleware exclusion coverHEADrequests (@Chaoqi31)fix(core): reset the listening state when the application closes (@Chaoqi31)
fix(core): hash
Map,SetandRegExpoptions in deep-hash tokens (@Chaoqi31)fix(core): treat
VERSION_NEUTRALin middleware routes as no version (@Chaoqi31)fix(core): turn off express
x-powered-byinuseSecurityHeaders()(@Chaoqi31)fix(core): name dynamic host modules in import error messages (@Chaoqi31)
fix(core): isolate nested transient providers injected into properties (@Chaoqi31)
microservicesfix(microservices): keep nats status updates alive when a listener throws (@kamilmysliwiec)
fix(microservices): default server options like the client factory does (@thekhegay)
fix(microservices): match rmq '#' wildcards in any position (@thekhegay)
fix(microservices): fail mqtt requests whose publish fails (@izg0820)
fix(microservices): preserve null payloads in kafka tombstone records (@Hangell)
fix(microservices): close the connection when the channel close fails (@hktitof)
fix(microservices): return the rmq reply publish so failures are handled (@maxymlyskov)
fix(microservices): fail redis listen on rejected subscriptions (@kamilmysliwiec)
fix(microservices): clone the kafka record before serializing (@Mihir-Rabari)
fix(microservices): do not crash when the redis connection drops (@maxymlyskov)
fix(microservices): fail pending kafka request on deserializer error (@hktitof)
fix(microservices): wait for the TCP TLS handshake (@jackie-cqz)
fix(microservices): survive custom deserializer errors in clients (@johnnyhuirilef)
fix(microservices): close both kafka client connections when one fails (@izg0820)
fix(microservices): unwrap records returned by message handlers (@johnnyhuirilef)
fix(microservices): wait for both Redis clients to be ready (@jackie-cqz)
fix(microservices): ignore stale NATS status events (@jackie-cqz)
fix(microservices): preserve MQTT payload options (@jackie-cqz)
fix(microservices): suspend incomplete packet timers during backpressure (@jackie-cqz)
fix(microservices): cancel pending TCP retries on close (@jackie-cqz)
fix(microservices): keep grpc response errors out of the request stream (@drakeo338)
fix(microservices): fail rmq connect and listen on channel setup errors (@johnnyhuirilef)
fix(microservices): run every event handler when a sibling completes empty (@johnnyhuirilef)
fix(microservices): fail nats requests on undecodable replies (@johnnyhuirilef)
fix(microservices): stop rmq client opening two channels on connect (@johnnyhuirilef)
fix(microservices): answer client-streaming calls that return nothing (@Chaoqi31)
fix(microservices): resolve grpc stream calls that complete empty (@hktitof)
platform-fastifyfix(fastify): answer the shutdown hooks 503 with fastify's json body (@kamilmysliwiec)
fix(fastify): honor
return503OnClosingduring the shutdown hooks (@thekhegay)fix(fastify): reject listen() on an invalid port (@kamilmysliwiec)
fix(fastify): listen on a socket path (@johnnyhuirilef)
fix(fastify): settle async lifecycle hooks once (@jackie-cqz)
fix(fastify): preserve custom router constraints (@jackie-cqz)
fix(fastify): keep the default body parsers after
useBodyParser()(@Chaoqi31)fix(fastify): count headers flushed on
reply.rawinisHeadersSent(@Chaoqi31)
commonfix(common): keep custom decorator data that has schema or pipes keys (@Ahmad-Mosha)
fix(common): reject arrays nested in ParseArrayPipe items (@KAPUIST)
fix(common): collect configurable module alias dependencies (@jackie-cqz)
fix(common): isolate file type regexp state (@jackie-cqz)
fix(common): preserve parent validation constraints (@jackie-cqz)
fix(common): let a redeclared
@Inject()property replace the parent's (@Chaoqi31)fix(common): keep inherited
@Optional()properties optional (@Chaoqi31)
microservices,websocketsfix(websockets, microservices): fallback to 'Error' for minified exception class names (@korrayt)
websocketsfix(websockets): copy the options object in the base ws exception filter (@Mihir-Rabari)
fix(websockets): log scoped gateway resolution errors without a hook (@basteez)
fix(websockets): pass gateway lifecycle hook errors to exception filters (@kamilmysliwiec)
fix(websockets): pass the pattern when a scoped handler fails to resolve (@kamilmysliwiec)
fix(websockets): use the hook name as pattern for request-scoped hooks (@OmBhandwaldar)
fix(websockets): retain shared contexts during disconnect hooks (@jackie-cqz)
common,core,platform-expressfix(common,core,express): answer method miss on an excluded route (@thekhegay)
platform-wsfix(ws): default omitted adapter creation options (@jackie-cqz)
core,websocketsfix(websockets): resolve global scoped enhancers per connection (@jackie-cqz)
core,testingfix(core): take the scope of the class in
useClass()overrides (@Chaoqi31)
Enhancements
platform-express,platform-fastifyfeat(express,fastify): add field nesting and array index upload limits (@KAPUIST)
Committers: 23
Abdellatif Anaflous (@hktitof)
Ahmed Gamal (@Ahmad-Mosha)
Aurora (@auroraxo)
Chaoqi (@Chaoqi31)
Dustin (@GiHoon1123)
Hangell (@Hangell)
Johnny J. Huirilef Millán (@johnnyhuirilef)
Kamil Mysliwiec (@kamilmysliwiec)
Lee Jae Hyun (@izg0820)
Luke Son (@KAPUIST)
Maksym Lyskov (@maxymlyskov)
Metehan Biçer (@Metehan-Bicer)
Micael Levi L. Cavalcante (@micalevisk)
Mohamed-Zakaria (@Mohamed-Elshesheny)
Om Bhandwaldar (@OmBhandwaldar)
Rabari Mihir (@Mihir-Rabari)
RedShapedMoon (@korrayt)
Roman Khegay (@thekhegay)
Tiziano Basile (@basteez)
Younes Beriane (@drakeo338)
jackie_cqz (@jackie-cqz)
Žan Mlakar (@zanmlakar)
12.1.2
30 Sep 202612.1.1
28 Sep 2026common,core,microservices,testingmicroservicescommon
Bug fixes
common,core,microservices,testingfix(common): logger bugs in json output, level changes, fatal and buffered logs (@kamilmysliwiec)
microservicesfix(microservices): let the mqtt client retry after a failed connect (@hktitof)
fix(microservices): keep tcp event listeners across reconnects (@KAPUIST)
fix(microservices): ignore events from a replaced tcp client socket (@KAPUIST)
fix(microservices): keep a newer nats connection when a stale one fails (@hktitof)
fix(microservices): keep a newer kafka connection when a stale one fails (@kamilmysliwiec)
fix(microservices): let the rmq client retry after a failed connect (@hktitof)
fix(microservices): reply on the request channel when redis wildcards are enabled (@fadiroot)
fix(microservices): recover the nats client after it gives up reconnecting (@xia-chao)
commonfix(common): preserve string enum values matching numeric member names (@KAPUIST)
corefix(core): detect circular dependencies across more than two providers (@erezcor)
platform-fastifyfix(fastify): treat a JSON content type with parameters as JSON in reply() (@fadiroot)
core,testingfix(core): honor class and factory overrides of value providers (@lehafari)
Enhancements
commonfix(common): reject non-numeric items in ParseArrayPipe with items Number (@SulimanAbdulrazzaq)
microservicesfeat(microservices): export deserializers from the package root (@lazerg)
Committers: 13
Abdellatif Anaflous (@hktitof)
Alejandro (@lehafari)
Daniel Pinto (@Cayan)
Dharmik Sondagar (@DharmikSondagar)
Kamil Mysliwiec (@kamilmysliwiec)
Lazizbek Ergashev (@lazerg)
Luke Son (@KAPUIST)
Micael Levi L. Cavalcante (@micalevisk)
Roman Khegay (@thekhegay)
Suliman Abdulrazzaq (@SulimanAbdulrazzaq)
Xia Chao (@xia-chao)
fadi romdhan (@fadiroot)
12.1.0
23 Sep 2026coremicroservicescore
Bug fixes
corefix(core): inherit optional ctor params when the ctor is not redeclared (@kamilmysliwiec)
fix(core): name the module when metadata entries are invalid (@thekhegay)
microservices
Enhancements
corecommon,corefeat(core): add support for array of global prefixes (@micalevisk)
feat(common,core): add built-in, adapter-agnostic cookies (@kamilmysliwiec)
platform-fastifyfix(fastify): honor Nest forceCloseConnections in initHttpServer (@xia-chao)
commonfix(common): apply the ParseDatePipe default to every missing value (@xia-chao)
platform-fastify,testingfeat(fastify): add file upload interceptors backed by @fastify/multipart (@kamilmysliwiec)
common,core,platform-fastifyfeat(common,core,fastify): built-in CSRF protection and security headers (@kamilmysliwiec)
Committers: 9
Abdellatif Anaflous (@hktitof)
Alejandro (@lehafari)
Chris Z (@haimingZZ)
Johnny J. Huirilef Millán (@johnnyhuirilef)
Jérémy Fauvel (@Grmiade)
Kamil Mysliwiec (@kamilmysliwiec)
Micael Levi L. Cavalcante (@micalevisk)
Roman Khegay (@thekhegay)
Xia Chao (@xia-chao)
12.0.4
21 Sep 2026microservicescoreplatform-express
Bug fixes
microservicesfix(microservices): let the kafka client retry after a failed connect (@Xch4rt)
fix(microservices): fail pending rmq requests on client close (@johnnyhuirilef)
fix(microservices): fail pending nats requests on client close (@hktitof)
fix(microservices): handle missing grpc package namespace gracefully (@Se3do)
fix(microservices): share the processing hook envelope across transports (@kamilmysliwiec)
fix(microservices): close the kafka request-response span exactly once (@MingLin1995)
fix(microservices): close the request-response span exactly once (@kamilmysliwiec)
fix(microservices): route message handler rejections to handleError (@hktitof)
corefix(core): hang on sparse factory inject array (@xia-chao)
Enhancements
platform-expressFix: merge multer
limitskey-by-key instead of overriding it wholesale (@mdrezuanislamridoy)
commonfix(common): mark parse date pipe options as optional (@Chy-Zaber-Bin-Zahid)
Committers: 10
Abdellatif Anaflous (@hktitof)
Chowdhury Zaber Bin Zahid (@Chy-Zaber-Bin-Zahid)
Imad - Prakticode (@prakticode)
Johnny J. Huirilef Millán (@johnnyhuirilef)
Kamil Mysliwiec (@kamilmysliwiec)
MD. Ridoy Babu (@mdrezuanislamridoy)
Ming (@MingLin1995)
Mohammed Said (@Se3do)
Pablo Gutiérrez (@Xch4rt)
Xia Chao (@xia-chao)
12.0.3
15 Sep 2026microservicescommonAbdellatif Anaflous (@hktitof)
Bug fixes
microservicesfix(microservices): always run the kafka processing end hook (@kamilmysliwiec)
fix(microservices): fail pending requests on client close (@hktitof)
fix(microservices): bound memory held for a TCP peer (@kamilmysliwiec)
fix(microservices): destroy open TCP sockets on shutdown (@kamilmysliwiec)
commonfix(common): validate uuid version and variant when no version is set (@otnc)
fix(common): invoke proto-key stripping hook via this in transform (@koreahghg)
Committers: 4
Abdellatif Anaflous (@hktitof)
Kamil Mysliwiec (@kamilmysliwiec)
otoneko. (@otnc)
한국 (@koreahghg)
12.0.2
14 Sep 2026platform-socket.io,platform-wsmicroservicescommon
Bug fixes
platform-socket.io,platform-wsfix(socket.io): keep the message stream alive when a handler throws (@hktitof)
microservicesfix(microservices): detach signal listeners of connected microservices (@kamilmysliwiec)
fix(microservices): fail requests whose reply subscription is rejected (@samuelmbabhazi)
fix(microservices): do not treat foreign JSON as an RPC envelope (@xia-chao)
fix(microservices): don't flatten plain handler results with pre-request hooks (@iamolegga)
fix(microservices): run the mqtt listen callback once (@johnnyhuirilef)
commonfix(common): collapse duplicate internal slashes in
normalizePath(@Asadshah7950)fix(common): validate UUID v3 variant (@gwagjiug)
fix(common): treat empty string as array input in ParseArrayPipe (@xia-chao)
corefix(core): discover factory providers with discovery decorators (@hktitof)
fix(core): avoid treating error instances with
statusCodeas http errors (@Asadshah7950)fix(core): clean up repeated shutdown signal listeners (@Raj4478)
platform-fastifyfix(fastify): derive neutral version when accept header is absent (@Gaurav1112)
fix(fastify): send responses for exceptions thrown from middleware (@micalevisk)
Enhancements
microservicesfeat(microservices): add maxConnectionAttempts to ServerMqtt (@kamilmysliwiec)
Committers: 16
Abdellatif Anaflous (@hktitof)
Alexey Solovyov (@lyohaplotinka)
Asad Ali Shah (@Asadshah7950)
Gyeonghun Park (@Gyeonghun-Park)
Johnny J. Huirilef Millán (@johnnyhuirilef)
Kamil Mysliwiec (@kamilmysliwiec)
Kumar Gaurav (@Gaurav1112)
Micael Levi L. Cavalcante (@micalevisk)
Ming (@MingLin1995)
Mohammed Said (@Se3do)
Rajeshwar Singh (@Raj4478)
Xia Chao (@xia-chao)
cui fliter (@cuishuang)
samuel mbabhazi (@samuelmbabhazi)
곽지욱 (@gwagjiug)
12.0.1
27 Aug 202612.0.0
27 Aug 2026nest upgrade(aliasupdate) — upgrades a v11 project to v12 and applies the migration steps described above.nest deploy— deploys your application to the cloud via Mau, installing@nestjs/mauon first use and forwarding every argument straight through.Rspack is the new default bundler for monorepos. The
--webpack/--webpackPathflags (and theirwebpack/webpackConfigPathcounterparts innest-cli.json) are deprecated in favor of--builder rspack.
NestJS v12.0.0
NestJS 12 is centered around ESM-ready packages, first-class Standard Schema support for validation and serialization, a rebuilt CLI, and native observability through the new
@nestjs/observeSDK.Existing CommonJS applications keep working — migrating your own code to ESM is entirely optional.
📖 Full migration guide
Upgrading
Upgrade the CLI first, since the upgrade command ships with it:
npm i -g @nestjs/cli@latest
Then, from the root of your project:
nest upgrade
nest upgrademoves every@nestjs/*package to its v12-compatible major at once and applies the mechanical parts of the migration for you —nest-cli.jsonwebpack options, the GraphQLplayground→graphiqlrename and subscriptions transport swap, the NATS package replacement,@nestjs/configvalidation options, Jest and Joi bumps — then prints a report of everything it changed and everything you still need to review by hand. Run it with--dry-runfirst to see that report without touching your files.It deliberately does not migrate your project to ESM, Vitest, or oxlint. Those are the defaults for newly generated projects; existing projects adopt them on their own schedule.
Node.js: v12 requires Node.js v20.19+ or v22.12+. Both
require(esm)and the ESM packages depend on it; the upgrade command refuses to run on older releases (including the 21.x line). The latest active LTS is recommended.Highlights
ESM packages
All core Nest packages now ship as ESM. Thanks to
require(esm)in modern Node.js, most existing CommonJS applications continue to work without a rewrite. Review custom bootstrapping scripts, build tooling, and test runners if they assume CommonJS-only packages.nest newnow asks whether to scaffold a CommonJS or an ESM project.Standard Schema validation
Route parameter decorators —
@Body(),@Query(),@Param(),@RawBody()— accept a newschemaoption, designed for Standard Schema compatible libraries such as Zod, Valibot, and ArkType:@Post() create(@Body({ schema: createUserSchema }) body: CreateUserDto) { return this.usersService.create(body); } @Get(':id') findOne(@Param('id', { schema: z.coerce.number().int().positive() }) id: number) { return this.usersService.findOne(id); }The decorator only attaches metadata; register the new
StandardSchemaValidationPipeto validate against it:app.useGlobalPipes(new StandardSchemaValidationPipe());
The same schemas feed OpenAPI generation. The decorator-based
class-validatorworkflow remains fully supported, with no plan to remove it.Standard Schema serialization
StandardSchemaSerializerInterceptorvalidates and transforms outgoing responses with the same ecosystem:@UseInterceptors(StandardSchemaSerializerInterceptor) @SerializeOptions({ schema: userResponseSchema }) @Get(':id') findOne(@Param('id') id: string) { return this.usersService.findOne(id); }Pick per use case:
ValidationPipe/ClassSerializerInterceptorfor class-based DTOs, the Standard Schema variants when your schemas already exist.Native observability —
@nestjs/observeThe official NestJS Observe SDK plugs into Nest's own request lifecycle through the
instrumentapplication option, rather than patching the HTTP server like a generic APM agent. Requests, jobs, errors, and traces are reported in terms of your controllers, providers, resolvers, and queue consumers:export const { ObserveModule, ObserveInstrument } = createObserveModule(); const app = await NestFactory.create(AppModule, { instrument: ObserveInstrument, });Auto-instrumentation covers HTTP, GraphQL, gRPC, and microservice transports, plus queue consumers and cron runs — no manual span wiring and no collector to run. Opt-in and new; nothing to migrate.
nest newandnest upgradecan wire it up for you (--observe). See the Observability chapter.Config module on Standard Schema
@nestjs/configmoves from Joi-specific validation to Standard Schema.validationSchemanow accepts any compatible schema:ConfigModule.forRoot({ validationSchema: z.object({ NODE_ENV: z.enum(['development', 'production', 'test']).default('development'), PORT: z.coerce.number().default(3000), }), });Existing Joi schemas still work with two caveats: upgrade to Joi v18+ (the first release implementing Standard Schema), and move library-specific settings under
validationOptions.libraryOptions.Route conflict diagnostics
Routes are registered in declaration order, so on order-sensitive adapters
@Get(':id')can silently shadow a@Get('me')declared after it. Two opt-in options surface this:const app = await NestFactory.create(AppModule, { routeConflictPolicy: { duplicate: 'error', shadow: 'warn' }, routeResolutionStrategy: 'specificity', });Both default to the previous behavior, so nothing changes unless you set them.
Machine-readable error codes
HttpExceptionOptionsaccepts anerrorCodethat is serialized into the response body, so clients branch on a stable identifier instead of parsing message strings:throw new BadRequestException('Password is too weak', { errorCode: 'WEAK_PASSWORD' });Structured logging params
ConsoleLoggernow treats plain objects passed after the message as structured params of the same log entry instead of separate records:logger.log('User created', { userId: 1, email: 'foo@bar.com' });In JSON mode they nest under
params, or spread into the root withflattenParams. On by default; setstructuredParams: falseto restore the old behavior.CLI (
@nestjs/cliv12)The CLI was rebuilt in nestjs/nest-cli#3280: the entire source migrated to ESM, tests moved from Jest to Vitest, e2e tests were added for every command, and command classes were refactored to take typed context objects instead of untyped inputs and option arrays.
New commands
nest upgrade(aliasupdate) — upgrades a v11 project to v12 and applies the migration steps described above.nest deploy— deploys your application to the cloud via Mau, installing@nestjs/mauon first use and forwarding every argument straight through.
Defaults and tooling
Rspack is the new default bundler for monorepos. The
--webpack/--webpackPathflags (and theirwebpack/webpackConfigPathcounterparts innest-cli.json) are deprecated in favor of--builder rspack.oxlint replaces ESLint in generated projects.
Vitest is the default test runner for ESM projects; CommonJS projects continue with Jest.
bun is now a supported package manager, alongside npm, yarn, and pnpm.
The
decoratorschematic generates decorators using the preferredReflector.createDecorator()form. Theangularschematic has been removed.
New options
nest build/nest start:--rspackPath [path],--emit-declarations(SWC),--no-type-check,--silentnest build:--parallel [concurrency], for building monorepo projects in parallel with--allnest-cli.json:includeLibraryAssets, for copying library assets into an application build
Breaking changes
Change What to do Packages ship as ESM Usually nothing — require(esm)keeps CommonJS apps working. Review custom bootstrapping, bundler, and test-runner config.Node.js v20.19+ / v22.12+ required Upgrade Node; the 21.x line is not supported. Lifecycle hooks are now invoked by component hierarchy level Review ordering assumptions between related providers/modules in init, teardown, and tests. NATS v3 — the natspackage is replaced by@nats-io/transport-nodenpm uninstall nats && npm install @nats-io/transport-node; update direct imports. Packets are now serialized as JSON strings and custom deserializers receive the full NATS message — read payloads withmsg.json().GraphQL subscriptions — subscriptions-transport-wssupport removedSwitch to graphql-ws; the protocols are wire-incompatible, so clients must be updated. ReviewonConnectcallbacks.GraphiQL is the default GraphQL IDE Replace playgroundwithgraphiql; pass an options object to customize.@nestjs/configvalidates through Standard SchemaKeep Joi by upgrading to v18+ and moving library settings under validationOptions.libraryOptions.Pipe transform signatures refined; ArgumentMetadatais now genericAdjust hand-written custom pipe signatures if the compiler complains. ConsoleLoggerstructured params on by defaultSet structuredParams: falseto restore the previous output.Webpack CLI workflows deprecated Migrate to --builder rspack.angularschematic removed— Most of these are handled automatically by
nest upgrade.Also in this release
ValidationPipeerror format — a new option controls the shape of validation error responses.gRPC exception filter —
GrpcExceptionFilterand status-specific exceptions map errors to proper gRPC status codes instead ofUNKNOWN.Regex Kafka patterns —
@MessagePattern()and@EventPattern()accept aRegExpon the Kafka transport.Request-scoped WebSocket gateways — gateways support request-scoped providers, with the socket injectable via the
REQUESTtoken.WebSocket disconnect reason —
handleDisconnectcan receive the reason for the disconnection.Microservices pre-request hook — a new hook runs before a message handler is invoked.
Express graceful shutdown — the Express adapter drains in-flight requests on shutdown.
HTTP adapter error mapping — reworked across core, Express, and Fastify adapters.
- 11.x
11.2.7
30 Sep 202611.2.6
23 Sep 202611.2.5
15 Sep 202611.2.4
14 Sep 2026microservices: handle unserializable patterns without crashing
platform-fastify: absolute-form request target middleware bypass
11.2.3
25 Aug 2026core: circular durable providers issue
11.2.1
14 Aug 2026core: early-return SSE abort issue
11.2.0
14 Aug 2026core: share existing singleton providers with lazily loaded modules
common: match string file types containing regex metacharacters
core: convert adjacent wildcard segments in legacy route converter
What's Changed
core: share existing singleton providers with lazily loaded modules
common: match string file types containing regex metacharacters
core: convert adjacent wildcard segments in legacy route converter
fastify: run middleware on routes excluded from global prefix
fastify: avoid double prefixing inherited middleware
core: scan pre-registered dynamic imports of lazy modules
core,common,platform-fastify: add query http method support
common: exclude reverse-mapped keys from numeric enum validation in ParseEnumPipe
core: sse signal
11.1.29
10 Aug 2026- removed
core: drop the g flag from middleware overlap regexes
core: stop import lookup after first direct export match
microservices: correct pub/sub client type in redis listeners
What's Changed
core: stop import lookup after first direct export match
microservices: correct pub/sub client type in redis listeners
common: add override mimetype option to file type validator
- removed
core: drop the g flag from middleware overlap regexes
core: support sse comments
core: resolve barrier immediately when target count is zero
common: exclude pipe options from validator options
core: serialize SSE retry field when value is zero
microservices: nullify grpcclient on close when tryshutdown fails
express: map missing multer field nesting error
11.1.28
8 Jul 2026Reading the note…
11.1.27
15 Jun 2026Reading the note…
11.1.26
8 Jun 2026Reading the note…
11.1.25
8 Jun 2026Reading the note…
11.1.24
25 May 2026Reading the note…
11.1.23
21 May 2026Reading the note…
11.1.22
21 May 2026Reading the note…
11.1.21
14 May 2026Reading the note…
11.1.20
13 May 2026Reading the note…
11.1.19
13 Apr 2026Reading the note…
11.1.18
3 Apr 2026Reading the note…
11.1.17
16 Mar 2026Reading the note…
11.1.16
5 Mar 2026Reading the note…
11.1.15
3 Mar 2026Reading the note…
11.1.14
17 Feb 2026Reading the note…
11.1.13
3 Feb 2026Reading the note…
11.1.12
15 Jan 2026Reading the note…
11.1.11
29 Dec 2025Reading the note…
11.1.10
22 Dec 2025Reading the note…
11.1.9
14 Nov 2025Reading the note…
11.1.8
27 Oct 2025Reading the note…
11.1.7
21 Oct 2025Reading the note…
11.1.6
7 Aug 2025Reading the note…
11.1.5
18 Jul 2025Reading the note…
11.1.4
16 Jul 2025Reading the note…
11.1.3
6 Jun 2025Reading the note…
11.1.2
26 May 2025Reading the note…
11.1.1
14 May 2025Reading the note…
11.1.0
23 Apr 2025Reading the note…
11.0.21
23 Apr 2025Reading the note…
11.0.20
16 Apr 2025Reading the note…