{"record":{"id":"003ec2919989e602","repo":"apereo/cas","slug":"could-not-extract-registered-services-from-request","errorCode":null,"errorMessage":"Could not extract registered services from request body","messagePattern":"Could not extract registered services from request body","errorType":"http","errorClass":null,"httpStatus":400,"severity":"error","filePath":"support/cas-server-support-reports-core/src/main/java/org/apereo/cas/web/report/RegisteredServicesEndpoint.java","lineNumber":416,"sourceCode":"    })\n    @ResponseBody\n    @Operation(summary = \"Update registered service supplied in the request body\",\n        parameters = @Parameter(name = \"body\", required = true, description = \"The request body to contain service definition\"))\n    public ResponseEntity updateService(\n        @RequestBody\n        final String registeredServiceBody) {\n        val registeredServiceSerializer = new RegisteredServiceJsonSerializer(applicationContext);\n        val registeredService = registeredServiceSerializer.from(registeredServiceBody);\n        val result = servicesManager.getObject().save(registeredService);\n        return ResponseEntity.ok(registeredServiceSerializer.toString(result));\n    }\n\n    private ResponseEntity<RegisteredService> importSingleService(final HttpServletRequest request) throws IOException {\n        val requestBody = IOUtils.toString(request.getInputStream(), StandardCharsets.UTF_8);\n        LOGGER.trace(\"Submitted registered service:\\n[{}]\", requestBody);\n\n        if (StringUtils.isBlank(requestBody)) {\n            LOGGER.warn(\"Could not extract registered services from request body\");\n            return ResponseEntity.badRequest().build();\n        }\n\n        return registeredServiceSerializers\n            .getObject()\n            .stream()\n            .map(serializer -> serializer.from(requestBody))\n            .filter(Objects::nonNull)\n            .findFirst()\n            .map(service -> {\n                LOGGER.trace(\"Storing registered service:\\n[{}]\", service);\n                return servicesManager.getObject().save(service);\n            })\n            .map(service -> {\n                val headers = new HttpHeaders();\n                headers.put(\"id\", CollectionUtils.wrapList(String.valueOf(service.getId())));\n                return new ResponseEntity<>(service, headers, HttpStatus.CREATED);\n            })","sourceCodeStart":398,"sourceCodeEnd":434,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-reports-core/src/main/java/org/apereo/cas/web/report/RegisteredServicesEndpoint.java#L398-L434","documentation":"importSingleService() reads the raw HTTP request body (expected to be a serialized registered service in JSON or another supported format) and rejects the request with HTTP 400 when the body is blank. CAS cannot import a service definition from an empty payload, so it logs this warning and returns badRequest without touching the registry.","triggerScenarios":"POSTing to the service import endpoint with an empty body, whitespace-only body, or when the request InputStream yields nothing (e.g. body not forwarded by a proxy or wrong Content-Type so the stream is already consumed).","commonSituations":"curl call missing -d/--data-binary; sending the service definition as multipart/form-data instead of a raw body; a reverse proxy or servlet filter consuming the InputStream before CAS reads it; copy-paste of an empty file.","solutions":["Send the service JSON as the raw request body, e.g. curl --data-binary @service.json -H 'Content-Type: application/json'","Log/print the request body (CAS already traces it) to confirm the server actually receives content","Check for filters/proxies that read or buffer the request InputStream before it reaches the endpoint","Ensure the HTTP method is POST/PUT with a body, not a GET"],"exampleFix":"// before: empty body\ncurl -X POST https://cas/v1/services/import\n// after\ncurl -X POST https://cas/v1/services/import \\\n  -H 'Content-Type: application/json' \\\n  --data-binary @service.json","handlingStrategy":"validation","validationCode":"// before sending\nconst body = fs.readFileSync('service.json', 'utf8');\nif (!body.trim()) throw new Error('service definition body is empty');","typeGuard":"function hasBody(req) { return req.body != null && String(req.body).trim().length > 0; }","tryCatchPattern":"val resp = post(importUrl, body);\nif (resp.status === 400) throw new Error('import rejected: empty/invalid body');","preventionTips":["Use --data-binary @file with curl to preserve the raw body","Send Content-Type: application/json","Check no proxy/filter consumes the request InputStream"],"tags":["rest","http-400","import","empty-body"],"backgroundTag":"empty-required-field","analyzedSha":"e7288fc434b4f4505b8452e1a57e8fb3111bb863","analyzedAt":"2026-09-08T15:39:16.015Z","contentChangedAt":"2026-09-08T15:39:16.015Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}