{"record":{"id":"9c5a94edafd61a61","repo":"opf/openproject","slug":"connection-to-jira-server-timed-out-message","errorCode":null,"errorMessage":"Connection to Jira server timed out: %{message}","messagePattern":"Connection to Jira server timed out: %(.+?)","errorType":"exception","errorClass":"Import::JiraClient::ConnectionError","httpStatus":null,"severity":"error","filePath":"app/services/import/jira_client.rb","lineNumber":275,"sourceCode":"          tempfile = Tempfile.create(filename, binmode: true)\n          response.read_body do |chunk|\n            tempfile.write chunk\n          end\n          yield tempfile\n        else\n          status = response.code.to_i\n          raise ApiError.new(I18n.t(\"admin.jira.client.api_error\", status:), status:, response_body: response.body)\n        end\n      end\n      nil\n    rescue SsrfFilter::PrivateIPAddress\n      raise SsrfError, I18n.t(\"admin.jira.client.ssrf_blocked\")\n    rescue SsrfFilter::Error => 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    ensure\n      File.unlink(tempfile) if tempfile\n    end\n\n    private\n\n    def get(path, params: {})\n      response = get_response(path, params:)\n      handle_response(response)\n    end\n\n    def get_response(path, params: {})\n      OpenProject::SsrfProtection.get(\n        \"#{@url}#{path}\",\n        headers: @headers,\n        params:,\n        http_options: HTTP_OPTIONS\n      )","sourceCodeStart":257,"sourceCodeEnd":293,"githubUrl":"https://github.com/opf/openproject/blob/d9742c43f3424c34b63550f8c03f201fe5c3040c/app/services/import/jira_client.rb#L257-L293","documentation":"In download_attachment, Timeout::Error (including Net::OpenTimeout/Net::ReadTimeout subclasses) is wrapped into Import::JiraClient::ConnectionError with this message. The client uses the frozen HTTP_OPTIONS = { open_timeout: 30, read_timeout: 30 }, so exceeding either limit while connecting to or streaming a Jira attachment raises; the original timeout detail is in %{message}.","triggerScenarios":"client.download_attachment where the TCP/TLS connect takes over 30s (typically a firewall silently dropping packets so the connect hangs), or the streamed attachment body stalls/pushes data slower than the 30s read timeout allows (large attachments on a slow or throttled link, paused Jira node).","commonSituations":"Containerized OpenProject with no route to the Jira network (packets blackholed instead of rejected); VPN/MTU problems that stall mid-transfer of large attachments; bulk imports hitting an overloaded Jira so responses trickle; nightly backup windows slowing the Jira host.","solutions":["Measure actual connectivity from the OpenProject host: curl -o /dev/null -w 'connect=%{time_connect} total=%{time_total}' '<attachment-url>'","If transfers legitimately exceed 30s, raise the timeouts (HTTP_OPTIONS is a frozen constant — patch it via an initializer/upstream change) or reduce attachment sizes","Retry the operation: transient congestion is the most common cause and a second attempt often succeeds","For recurring stalls, check path MTU/VPN encapsulation and Jira-side GC pauses"],"exampleFix":"# before\nclient.download_attachment(content_url, filename) { |tf| attach(tf) }\n\n# after — retry transient timeouts with backoff\nattempts = 0\nbegin\n  attempts += 1\n  client.download_attachment(content_url, filename) { |tf| attach(tf) }\nrescue Import::JiraClient::ConnectionError => e\n  raise if attempts >= 3 || !e.message.include?(\"timed out\")\n  sleep(2**attempts)\n  retry\nend","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"attempts = 0\nbegin\n  attempts += 1\n  client.download_attachment(content_url, filename) { |tf| attach(tf) }\nrescue Import::JiraClient::ConnectionError => e\n  raise if attempts >= 3 || !e.message.include?(\"timed out\")\n  sleep(2**attempts)\n  retry\nend","preventionTips":["Bound retries (2-3) with exponential backoff; a hard 30s timeout repeated forever just stalls the import","Record which attachments failed so a later pass can re-fetch only those","Baseline the attachment fetch time from the OpenProject host before starting a large import"],"tags":["jira","timeout","network","import","attachments"],"backgroundTag":"request-timeout","analyzedSha":"d9742c43f3424c34b63550f8c03f201fe5c3040c","analyzedAt":"2026-08-21T14:40:06.829Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}