{"record":{"id":"568e18e4a8f1c7b0","repo":"SonarSource/sonarqube","slug":"http-method-post-is-required","errorCode":null,"errorMessage":"HTTP method POST is required","messagePattern":"HTTP method POST is required","errorType":"http","errorClass":"ServerException","httpStatus":405,"severity":"error","filePath":"server/sonar-webserver-ws/src/main/java/org/sonar/server/ws/RequestVerifier.java","lineNumber":37,"sourceCode":" */\npackage org.sonar.server.ws;\n\nimport org.sonar.api.server.ws.Request;\nimport org.sonar.api.server.ws.WebService;\nimport org.sonar.server.exceptions.ServerException;\n\nimport static jakarta.servlet.http.HttpServletResponse.SC_METHOD_NOT_ALLOWED;\n\npublic class RequestVerifier {\n  private RequestVerifier() {\n    // static methods only\n  }\n\n  public static void verifyRequest(WebService.Action action, Request request) {\n    switch (request.method()) {\n      case \"GET\":\n        if (action.isPost()) {\n          throw new ServerException(SC_METHOD_NOT_ALLOWED, \"HTTP method POST is required\");\n        }\n        break;\n      case \"POST\":\n        if (!action.isPost()) {\n          throw new ServerException(SC_METHOD_NOT_ALLOWED, \"HTTP method GET is required\");\n        }\n        break;\n      default:\n        throw new ServerException(SC_METHOD_NOT_ALLOWED, String.format(\"HTTP method %s is not allowed\", request.method()));\n    }\n  }\n}\n","sourceCodeStart":19,"sourceCodeEnd":50,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/server/sonar-webserver-ws/src/main/java/org/sonar/server/ws/RequestVerifier.java#L19-L50","documentation":"Thrown by RequestVerifier.verifyRequest when a GET request is issued against a web service action declared as POST-only. The server responds with HTTP 405 Method Not Allowed telling the client the action requires POST.","triggerScenarios":"Issuing GET (e.g. in a browser address bar or curl without -X POST) to a POST action such as api/webhooks/create, api/issues/do_transition, api/user_tokens/generate (POST-declared actions).","commonSituations":"Pasting a POST-only API URL into a browser to 'test' it; scripts using the default curl GET; REST clients defaulting to GET; copying a URL from docs without matching the documented HTTP verb.","solutions":["Resend the request with -X POST (plus required params as form/body parameters).","Check the endpoint's declared method in the web service documentation and use the listed verb.","If a GET variant exists, use the appropriate action rather than forcing GET on the POST one."],"exampleFix":"// before\ncurl -u $TOKEN \"$SONAR/api/user_tokens/generate?name=ci\" // 405 POST required\n// after\ncurl -u $TOKEN -X POST \"$SONAR/api/user_tokens/generate?name=ci\"","handlingStrategy":"validation","validationCode":"# enforce the verb before calling\nVERB=$(grep -o 'POST' <<< \"$ENDPOINT_SPEC\" || echo GET)\n[ \"$HTTP_METHOD\" = \"$VERB\" ] || { echo \"Use $VERB for $PATH\"; exit 1; }","typeGuard":null,"tryCatchPattern":"if (response.code() == 405 && response.message().contains(\"POST is required\")) {\n  retryAsPost();\n}","preventionTips":["Check the HTTP verb in the API docs for every endpoint used in scripts.","Never 'test' POST endpoints in the browser address bar.","Encode the verb alongside the URL in shared request collections."],"tags":["http-405","method-not-allowed","web-api","http-verb"],"backgroundTag":"http-error-response","analyzedSha":"184c821202192afc1c599fc912d0889b69fffa53","analyzedAt":"2026-09-09T12:23:51.573Z","contentChangedAt":"2026-09-09T12:23:51.573Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}