{"record":{"id":"232ff694e1ca29eb","repo":"alibaba/Sentinel","slug":"only-form-encoded-post-request-is-supported","errorCode":null,"errorMessage":"Only form-encoded post request is supported","messagePattern":"Only form-encoded post request is supported","errorType":"http","errorClass":"RequestException","httpStatus":415,"severity":"warning","filePath":"sentinel-transport/sentinel-transport-simple-http/src/main/java/com/alibaba/csp/sentinel/transport/command/http/HttpEventTask.java","lineNumber":179,"sourceCode":"     * @param in\n     * @param request\n     * @throws RequestException\n     * @throws IOException\n     */\n    protected static void processPostRequest(InputStream in, CommandRequest request)\n        throws RequestException, IOException {\n        Map<String, String> headerMap = parsePostHeaders(in);\n\n        if (headerMap == null) {\n            // illegal request\n            CommandCenterLog.warn(\"Illegal request read: null headerMap\");\n            throw new RequestException(StatusCode.BAD_REQUEST, \"\");\n        }\n\n        if (headerMap.containsKey(\"content-type\") && !checkContentTypeSupported(headerMap.get(\"content-type\"))) {\n            // not supported Content-type\n            CommandCenterLog.warn(\"Request not supported: unsupported Content-Type: \" + headerMap.get(\"content-type\"));\n            throw new RequestException(StatusCode.UNSUPPORTED_MEDIA_TYPE,\n                \"Only form-encoded post request is supported\");\n        }\n\n        int bodyLength = 0;\n        try {\n            bodyLength = Integer.parseInt(headerMap.get(\"content-length\"));\n        } catch (Exception e) {\n        }\n        if (bodyLength < 1) {\n            // illegal request without Content-length header\n            CommandCenterLog.warn(\"Request not supported: no available Content-Length in headers\");\n            throw new RequestException(StatusCode.LENGTH_REQUIRED, \"No legal Content-Length\");\n        }\n\n        parseParams(readBody(in, bodyLength), request);\n    }\n\n    /**","sourceCodeStart":161,"sourceCodeEnd":197,"githubUrl":"https://github.com/alibaba/Sentinel/blob/a3f40ba8e900c8489bd520274739f17235a7721c/sentinel-transport/sentinel-transport-simple-http/src/main/java/com/alibaba/csp/sentinel/transport/command/http/HttpEventTask.java#L161-L197","documentation":"The simple-http command center only accepts POST requests with Content-Type application/x-www-form-urlencoded (URL-encoded form). checkContentTypeSupported rejects everything else, and processPostRequest throws RequestException(StatusCode.UNSUPPORTED_MEDIA_TYPE, \"Only form-encoded post request is supported\"), which is returned to the client as HTTP 415. This is a deliberate protocol restriction, not a bug.","triggerScenarios":"curl -X POST http://host:8719/modifyRules -H 'Content-Type: application/json' -d '{...}' — any JSON, multipart, or text/plain POST to the simple-http command port returns 415 with this message.","commonSituations":"Dashboard or automation scripts pushing rule changes as JSON to a client using sentinel-transport-simple-http; switching transports (netty-http has different constraints); hand-written integration assuming generic HTTP POST.","solutions":["Send form-encoded bodies: curl -d 'key=value' (curl's default Content-Type) without overriding the header","URL-encode rule payloads into form parameters per the handler's expected parameter names","If JSON posts are a hard requirement, switch the client to a custom command center implementation or push rules via the datasource (Nacos/Apollo/ZooKeeper) instead of the transport API"],"exampleFix":"# before\ncurl -X POST http://localhost:8719/modifyFlowRules -H 'Content-Type: application/json' -d '[{...}]'\n\n# after\ncurl -X POST http://localhost:8719/modifyFlowRules -d 'data=%5B%7B...%7D%5D'","handlingStrategy":"validation","validationCode":"// client-side: let the HTTP library set the default form content type\n// curl: omit -H 'Content-Type'; Java: URL-encoded form entity\n// explicit check before send:\nif (!\"application/x-www-form-urlencoded\".equals(myContentType)) {\n    throw new IllegalStateException(\"simple-http transport requires form encoding\");\n}","typeGuard":null,"tryCatchPattern":"if (status == 415) {\n    // re-send as application/x-www-form-urlencoded with urlencoded body\n}","preventionTips":["Never POST JSON to the simple-http command port","Prefer datasource-based (Nacos/Apollo) rule pushing for structured payloads"],"tags":["sentinel","transport","http","content-type","simple-http"],"backgroundTag":null,"analyzedSha":"a3f40ba8e900c8489bd520274739f17235a7721c","analyzedAt":"2026-08-14T11:10:30.678Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}