{"record":{"id":"a886abe65b6e1933","repo":"nestjs/nest","slug":"cannot-method-url","errorCode":null,"errorMessage":"Cannot ${method} ${url}","messagePattern":"Cannot (.+?) (.+?)","errorType":"http","errorClass":"NotFoundException","httpStatus":404,"severity":"warning","filePath":"packages/core/router/routes-resolver.ts","lineNumber":160,"sourceCode":"        };\n        this.routerExplorer.explore(\n          instanceWrapper,\n          moduleName,\n          applicationRef,\n          host!,\n          routePathMetadata,\n          options,\n        );\n      });\n    });\n  }\n\n  public registerNotFoundHandler() {\n    const applicationRef = this.container.getHttpAdapterRef();\n    const callback = <TRequest, TResponse>(req: TRequest, res: TResponse) => {\n      const method = applicationRef.getRequestMethod(req);\n      const url = applicationRef.getRequestUrl(req);\n      throw new NotFoundException(`Cannot ${method} ${url}`);\n    };\n    const handler = this.routerExceptionsFilter.create({}, callback, undefined);\n    const proxy = this.routerProxy.createProxy(callback, handler);\n    const prefix = this.applicationConfig.getGlobalPrefix();\n    applicationRef.setNotFoundHandler &&\n      applicationRef.setNotFoundHandler(proxy, prefix);\n  }\n\n  public registerExceptionHandler() {\n    const callback = <TError, TRequest, TResponse>(\n      err: TError,\n      req: TRequest,\n      res: TResponse,\n      next: Function,\n    ) => {\n      throw this.container.getHttpAdapterRef().mapException(err);\n    };\n    const handler = this.routerExceptionsFilter.create(","sourceCodeStart":142,"sourceCodeEnd":178,"githubUrl":"https://github.com/nestjs/nest/blob/dd75d7bd8c5e88048587e6768d36eb695f3e7a25/packages/core/router/routes-resolver.ts#L142-L178","documentation":"This is the framework's built-in not-found handler: after route registration NestJS installs a catch-all callback that throws `NotFoundException('Cannot <method> <url>')` for any request no route matched, producing the standard 404 body. Seeing it means the router had no matching handler — which may be perfectly correct behavior, or a symptom that your routes/prefix/versioning are not registered the way you think.","triggerScenarios":"Requesting a misspelled or missing path; a global prefix (set via `app.setGlobalPrefix('api')`) that the caller omitted or doubled; URI versioning enabled so the real path is `/v1/users` while `/users` 404s; the controller not being listed in its module's `controllers`; route params mismatching (e.g., `@Get('users/:id')` but requesting `/users/1/orders`) so the more specific path 404s.","commonSituations":"Frontend hardcoded paths drifting from backend routes after adding a global prefix; API consumers forgetting the version segment; proxy/gateway stripping or adding path prefixes; controllers forgotten in modules after refactors; HTTP method confusion (POST-only route hit with GET yields 404, not 405, since no route matches).","solutions":["Compare the exact URL and method against your registered routes (log them from the router or check the OpenAPI/Explorer output).","Account for `setGlobalPrefix` and versioning in the URL you call.","Make sure the controller class is declared in the module's `controllers` array and the module is imported.","If the 404 is expected, keep it — or replace the default handler/exception mapping with a custom one for a better payload."],"exampleFix":"// before: client calls /users but app uses prefix\nawait app.setGlobalPrefix('api');\n// GET /users -> Cannot GET /users\n\n// after\n// GET /api/users -> 200\n// or drop the prefix if the contract requires /users","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Map the default 404 to a useful payload for API consumers\nimport { Catch, NotFoundException, ExceptionFilter, ArgumentsHost } from '@nestjs/common';\n\n@Catch(NotFoundException)\nexport class NotFoundFilter implements ExceptionFilter {\n  catch(_: NotFoundException, host: ArgumentsHost) {\n    const ctx = host.switchToHttp();\n    ctx.getResponse().status(404).json({\n      statusCode: 404,\n      error: 'Not Found',\n      hint: 'Check the global prefix and route versioning (e.g. /api/v1/...)',\n    });\n  }\n}","preventionTips":["Publish the OpenAPI spec so clients derive URLs from the app instead of hardcoding them.","Cover global prefix + versioning in route smoke tests run against the started app.","Add an explorability/health route at root to distinguish 'app up, path wrong' from 'app down'.","Treat 404s as expected outcomes in clients and handle them explicitly rather than as errors."],"tags":["http-404","routing","not-found","global-prefix"],"backgroundTag":"http-404-not-found","analyzedSha":"dd75d7bd8c5e88048587e6768d36eb695f3e7a25","analyzedAt":"2026-08-21T19:39:39.867Z","contentChangedAt":"2026-08-21T19:39:39.867Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}