{"id":"7a8d42b9825951cd","repo":"nestjs/nest","slug":"on-method-not-supported-by-the-underlying-server","errorCode":null,"errorMessage":"\"on\" method not supported by the underlying server","messagePattern":"\"on\" method not supported by the underlying server","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/microservices/nest-microservice.ts","lineNumber":334,"sourceCode":"\n  /**\n   * Sets the flag indicating that the init hook was called.\n   * @param isInitHookCalled Value to set\n   */\n  public setIsInitHookCalled(isInitHookCalled: boolean) {\n    this.wasInitHookCalled = isInitHookCalled;\n  }\n\n  /**\n   * Registers an event listener for the given event.\n   * @param event Event name\n   * @param callback Callback to be executed when the event is emitted\n   */\n  public on(event: string | number | symbol, callback: Function) {\n    if ('on' in this.serverInstance) {\n      return this.serverInstance.on(event as string, callback);\n    }\n    throw new Error('\"on\" method not supported by the underlying server');\n  }\n\n  /**\n   * Returns an instance of the underlying server/broker instance,\n   * or a group of servers if there are more than one.\n   */\n  public unwrap<T>(): T {\n    if ('unwrap' in this.serverInstance) {\n      return this.serverInstance.unwrap();\n    }\n    throw new Error('\"unwrap\" method not supported by the underlying server');\n  }\n\n  protected async closeApplication(): Promise<any> {\n    this.socketModule && (await this.socketModule.close());\n    this.microservicesModule && (await this.microservicesModule.close());\n\n    await super.close();","sourceCodeStart":316,"sourceCodeEnd":352,"githubUrl":"https://github.com/nestjs/nest/blob/6ec0e2783d15290732447f304d8549b591b9749e/packages/microservices/nest-microservice.ts#L316-L352","documentation":"Thrown by NestMicroservice.on() when the underlying serverInstance does not have an 'on' method (the runtime checks \"on\" in this.serverInstance). The hybrid NestMicroservice wrapper exposes on()/unwrap() generically, but delegates to the concrete server; if that server's transport does not implement event subscription (notably ServerGrpc.on() throws its own 'not supported in gRPC mode' message, and custom servers may omit on()), the wrapper falls through to this generic rejection.","triggerScenarios":"Calling app.on(event, cb) (or microservice.on(...)) on a NestMicroservice whose server is a gRPC server or a custom Server subclass that does not define on(). Generic lifecycle code that attaches listeners to whatever microservice is running.","commonSituations":"Mixing gRPC into a hybrid app and trying to subscribe to server events via the microservice handle. A custom Server implementation without on(). Code written for TCP/Redis servers that assumes every server supports on().","solutions":["For status, use the per-transport status Observable on the server/client instead of microservice.on().","If you need on(), use a transport whose Server implements it (TCP/Redis/RMQ/MQTT/NATS) or add an on() method to your custom Server subclass.","Avoid calling on() on a gRPC-backed NestMicroservice — gRPC events are surfaced differently."],"exampleFix":"// before\nconst app = await NestFactory.createMicroservice(AppModule, { transport: Transport.GRPC, options: {...} });\napp.on('connection', fn); // throws\n\n// after\n// gRPC does not support on(); use client.status / gRPC interceptors for lifecycle hooks\n// or switch transport if you need this API","handlingStrategy":"type-guard","validationCode":"function supportsOn(server: any): boolean {\n  return server && 'on' in server && typeof server.on === 'function'\n    && !/GRPC/.test(server.constructor?.name);\n}\nif (supportsOn(server)) server.on(event, cb);\nelse { /* use status Observable or transport-specific hook */ }","typeGuard":"import { ServerGrpc } from '@nestjs/microservices';\nconst supportsServerOn = (s: any): boolean => !(s instanceof ServerGrpc) && 'on' in s;","tryCatchPattern":"try {\n  app.on(event, cb);\n} catch (e) {\n  if (/\"on\" method not supported/.test(e?.message)) { /* use status / transport-specific API */ }\n  else throw e;\n}","preventionTips":["Do not call on() on a gRPC-backed NestMicroservice.","Branch generic lifecycle code by transport type.","Use client/server status Observables instead of on() where possible."],"tags":["microservice","server","events","grpc","typescript"],"analyzedSha":"6ec0e2783d15290732447f304d8549b591b9749e","analyzedAt":"2026-08-03T17:42:23.673Z","schemaVersion":2}