{"record":{"id":"57370ab678725edd","repo":"opf/openproject","slug":"jira-api-returned-a-429-error-it-means-token-owne","errorCode":null,"errorMessage":"Jira API returned a 429 error. It means token owner has been rate limited by the Jira instance. Please disable rate limiting for this user.","messagePattern":"Jira API returned a 429 error\\. It means token owner has been rate limited by the Jira instance\\. Please disable rate limiting for this user\\.","errorType":"exception","errorClass":"Import::JiraClient::ApiError","httpStatus":429,"severity":"error","filePath":"app/services/import/jira_client.rb","lineNumber":309,"sourceCode":"        params:,\n        http_options: HTTP_OPTIONS\n      )\n    rescue SsrfFilter::PrivateIPAddress\n      raise SsrfError, I18n.t(\"admin.jira.client.ssrf_blocked\")\n    rescue SsrfFilter::Error, SocketError, Errno::ECONNREFUSED, Errno::EHOSTUNREACH => e\n      raise ConnectionError, I18n.t(\"admin.jira.client.connection_error\", message: e.message)\n    rescue OpenSSL::SSL::SSLError => e\n      raise ConnectionError, I18n.t(\"admin.jira.client.ssl_error\", message: e.message)\n    rescue Timeout::Error => e\n      raise ConnectionError, I18n.t(\"admin.jira.client.connection_timeout\", message: e.message)\n    end\n\n    def handle_response(response)\n      status = response.code.to_i\n      if response.is_a?(Net::HTTPSuccess)\n        parse_json(response)\n      else\n        raise ApiError.new(\n          I18n.t(\"admin.jira.client.#{status}_error\", status:, default: :\"admin.jira.client.api_error\"),\n          status:,\n          response_body: response.body.to_s\n        )\n      end\n    end\n\n    def parse_json(response)\n      JSON.parse(response.body)\n    rescue JSON::ParserError => e\n      raise ParseError, I18n.t(\"admin.jira.client.parse_error\", message: e.message)\n    end\n  end\nend\n","sourceCodeStart":291,"sourceCodeEnd":324,"githubUrl":"https://github.com/opf/openproject/blob/d9742c43f3424c34b63550f8c03f201fe5c3040c/app/services/import/jira_client.rb#L291-L324","documentation":"Import::JiraClient#handle_response maps HTTP 429 to an ApiError with the admin.jira.client.429_error message. Jira (Data Center/Server has a user-level rate limer) throttled the token owner, so the importer's rapid sequential GET/POST loop is being rejected. The client has no automatic backoff, so the error aborts the current operation.","triggerScenarios":"A Jira import run (bulk project/issue/custom-field fetching) against a Jira DC instance where 'Rate limiting' is enabled for the importing user or globally, causing /rest/api/2 calls to return 429 mid-run.","commonSituations":"Jira DC rate limiting introduced/enabled by an admin after initial testing; large Jira instances where the import volume trips the default limits; shared token also used by other tooling consuming the quota.","solutions":["As the message instructs: in Jira DC go to Administration → System → Rate limiting and disable it (or raise limits) for the importing user, then retry the run.","If disabling is not possible, wait for the limit window to reset and retry the import run during off-peak hours.","Reduce concurrent Jira integrations using the same account so the import run has headroom."],"exampleFix":"# before\nretries = 0\nbegin\n  client.get('/rest/api/2/mypermissions')\nrescue Import::JiraClient::ApiError => e\n  retries += 1\n  retry\nend\n\n# after (backoff only on 429)\nretries = 0\nbegin\n  client.get('/rest/api/2/mypermissions')\nrescue Import::JiraClient::ApiError => e\n  raise if e.status != 429 || retries >= 5\n  retries += 1\n  sleep(2**retries)\n  retry\nend","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"retries = 0\nbegin\n  client.get('/rest/api/2/mypermissions')\nrescue Import::JiraClient::ApiError => e\n  raise unless e.status == 429 && retries < 5\n  retries += 1\n  sleep(2**retries)\n  retry\nend","preventionTips":["Disable or raise Jira DC user-level rate limits for the importing account before starting a run.","Wrap bulk Jira calls in 429-aware exponential backoff instead of failing the whole run.","Don't share the importing account with other integrations that consume the same quota."],"tags":["jira-import","http-429","rate-limiting","throttling"],"backgroundTag":"http-429-rate-limited","analyzedSha":"d9742c43f3424c34b63550f8c03f201fe5c3040c","analyzedAt":"2026-08-21T14:40:06.829Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}