{"record":{"id":"0f5368c5d20f91f2","repo":"pinpoint-apm/pinpoint","slug":"cannot-delete-reserved-service","errorCode":null,"errorMessage":"Cannot delete reserved service: ","messagePattern":"Cannot delete reserved service: ","errorType":"http","errorClass":"ResponseStatusException","httpStatus":400,"severity":"warning","filePath":"service-module/src/main/java/com/navercorp/pinpoint/service/web/controller/ServiceRegistryController.java","lineNumber":71,"sourceCode":"    public List<String> getServiceNames() {\n        return serviceRegistryService.getServiceNames();\n    }\n\n    // TODO: (minwoo) 이게 진짜 필요한지 추후 검토 필요함.\n    @GetMapping(\"/service\")\n    public ResponseEntity<ServiceView> getService(@RequestParam(\"serviceName\") @NotBlank String serviceName) {\n        Service service = serviceRegistryService.getService(serviceName);\n        if (service == null) {\n            return ResponseEntity.noContent().build();\n        }\n        return ResponseEntity.ok(ServiceView.of(service));\n    }\n\n    @PreAuthorize(\"hasPermission(#serviceName, null, T(com.navercorp.pinpoint.web.security.PermissionChecker).PERMISSION_SERVICEAUTHORIZATION_EDIT_AUTHOR_ONLY_MANAGER)\")\n    @DeleteMapping(\"/service\")\n    public Response deleteService(@RequestParam(\"serviceName\") @NotBlank String serviceName) {\n        if (reservedServiceRegistry.contains(serviceName)) {\n            throw new ResponseStatusException(HttpStatus.BAD_REQUEST,\n                    \"Cannot delete reserved service: \" + serviceName);\n        }\n        serviceRegistryService.deleteService(serviceName);\n        return SimpleResponse.ok();\n    }\n}\n","sourceCodeStart":53,"sourceCodeEnd":78,"githubUrl":"https://github.com/pinpoint-apm/pinpoint/blob/744c3d3075e595656abb1ae331ad2c0e4c9eb996/service-module/src/main/java/com/navercorp/pinpoint/service/web/controller/ServiceRegistryController.java#L53-L78","documentation":"deleteService refuses to delete any service whose name is in reservedServiceRegistry, throwing ResponseStatusException with HTTP 400. Reserved services are protected from accidental removal since they are required by the platform.","triggerScenarios":"DELETE /service?serviceName=<reservedName> by a user holding the edit-permission-manager role for that service's authorization.","commonSituations":"Cleanup scripts iterating over all services and deleting them, hitting built-in/reserved services; admins mistaking reserved services for stale entries.","solutions":["Skip reserved names in bulk-delete logic by checking reservedServiceRegistry.contains(name) first (admin-side) or filtering the list from the API.","Delete only user-created services.","If the name must be freed, change the reserved registry configuration rather than deleting via this endpoint."],"exampleFix":"// before\ndeleteService(\"RESERVED_NAME\");\n// after\nif (!reservedServiceRegistry.contains(name)) {\n    deleteService(name);\n}","handlingStrategy":"validation","validationCode":"if (reservedServiceRegistry.contains(serviceName)) { /* skip delete */ }","typeGuard":null,"tryCatchPattern":"try { rest.delete(\"/service?serviceName=\" + name); } catch (HttpClientErrorException e) { /* 400 reserved name — skip */ }","preventionTips":["Filter reserved services out of bulk-delete lists","Require explicit confirmation for delete operations"],"tags":["rest-api","reserved-name","http-400"],"backgroundTag":"permission-denied","analyzedSha":"744c3d3075e595656abb1ae331ad2c0e4c9eb996","analyzedAt":"2026-09-07T18:48:45.289Z","contentChangedAt":"2026-09-07T18:48:45.289Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}