{"record":{"id":"bf90fbbaf7051fe1","repo":"nestjs/nest","slug":"an-unsupported-event-was-received-it-has-been-neg","errorCode":null,"errorMessage":"An unsupported event was received. It has been negative acknowledged, so it will not be re-delivered. Pattern: ${pattern}","messagePattern":"An unsupported event was received\\. It has been negative acknowledged, so it will not be re-delivered\\. Pattern: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/microservices/server/server-rmq.ts","lineNumber":358,"sourceCode":"            properties.replyTo,\n            properties.correlationId,\n            rmqContext,\n          );\n\n        response$ && this.send(response$, publish);\n      },\n    );\n  }\n\n  public async handleEvent(\n    pattern: string,\n    packet: ReadPacket,\n    context: RmqContext,\n  ): Promise<any> {\n    const handler = this.getHandlerByPattern(pattern);\n    if (!handler && !this.noAck) {\n      this.channel!.nack(context.getMessage() as Message, false, false);\n      return this.logger.warn(RMQ_NO_EVENT_HANDLER`${pattern}`);\n    }\n    return super.handleEvent(pattern, packet, context);\n  }\n\n  public sendMessage<T = any>(\n    message: T,\n    replyTo: any,\n    correlationId: string,\n    context: RmqContext,\n  ): void {\n    const outgoingResponse = this.serializer.serialize(\n      message as unknown as OutgoingResponse,\n    );\n    const options = outgoingResponse.options;\n    delete outgoingResponse.options;\n\n    const buffer = Buffer.from(JSON.stringify(outgoingResponse));\n    const sendOptions = { correlationId, ...options };","sourceCodeStart":340,"sourceCodeEnd":376,"githubUrl":"https://github.com/nestjs/nest/blob/dd75d7bd8c5e88048587e6768d36eb695f3e7a25/packages/microservices/server/server-rmq.ts#L340-L376","documentation":"ServerRMQ.handleEvent received an event (a packet without an `id`, fire-and-forget) whose pattern matches no @EventPattern handler. In manual-ack mode (noAck false) the server nacks the message with requeue=false — RabbitMQ drops it permanently, no redelivery — and returns this warning. Unlike the message case there is no reply channel, so the emitting client gets no error: the event is simply lost, which makes this the more dangerous variant.","triggerScenarios":"client.emit(pattern, payload) where the pattern does not exactly match any @EventPattern(pattern) on the server (typo, casing, or object-pattern JSON key-order mismatch). Also events published to the service's queue by external producers without the expected {pattern, data} shape, and rolling deploys where a producer emits new event names before the consumer registers them.","commonSituations":"Event-name typos between producer and consumer services; renaming events without draining queues; several services sharing one queue so events land on an instance lacking the handler; external systems publishing directly to the queue; new events deployed producer-first.","solutions":["Align the pattern literal on producer and consumer (exact string or shared constant); object patterns must serialize identically.","Use a dedicated queue per microservice so events are never round-robined to services without the handler.","Add a dead-letter exchange to the queue so dropped unsupported events are inspectable, and alert on its depth.","Deploy order matters: register the @EventPattern consumer before producers start emitting the new pattern.","Purge queues after renaming or removing event patterns."],"exampleFix":"// before\n// producer\nthis.client.emit('order-created', order);\n// consumer\n@EventPattern('order_created') // underscore vs dash -> nack, event lost silently\n\n// after\nexport const ORDER_CREATED = 'order-created'; // shared constants package\nthis.client.emit(ORDER_CREATED, order);\n@EventPattern(ORDER_CREATED)\nonOrderCreated(@Payload() order: Order) { /* ... */ }","handlingStrategy":"validation","validationCode":"// events are fire-and-forget: no error comes back, so validate before emit\nexport const EVENTS = ['order-created', 'order-cancelled'] as const;\nexport type DomainEvent = (typeof EVENTS)[number];\n\nfunction assertKnownEvent(e: string): asserts e is DomainEvent {\n  if (!(EVENTS as readonly string[]).includes(e)) {\n    throw new Error(`Unknown event '${e}': consumer has no @EventPattern for it`);\n  }\n}\n\nassertKnownEvent(eventName);\nthis.client.emit(eventName, payload);","typeGuard":"const EVENTS = ['order-created', 'order-cancelled'] as const;\ntype DomainEvent = (typeof EVENTS)[number];\nconst isDomainEvent = (e: string): e is DomainEvent =>\n  (EVENTS as readonly string[]).includes(e);","tryCatchPattern":null,"preventionTips":["Share event-name constants between producer and consumer packages","One queue per microservice — shared queues round-robin events to services lacking the handler","Dead-letter the queue and alert on DLQ depth: unsupported events are otherwise dropped with zero client-side signal","Deploy consumers before producers when introducing new events","Watch server logs for this warning in production and map the pattern back to the offending producer"],"tags":["rabbitmq","amqp","event-routing","pattern-mismatch","nack","dead-letter"],"backgroundTag":"message-pattern-no-handler","analyzedSha":"dd75d7bd8c5e88048587e6768d36eb695f3e7a25","analyzedAt":"2026-08-21T19:39:39.867Z","contentChangedAt":"2026-08-21T19:39:39.867Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}