{"record":{"id":"b49492565545852c","repo":"instructure/canvas-lms","slug":"could-not-retrieve-configuration-the-server-response-timed","errorCode":null,"errorMessage":"could not retrieve configuration, the server response timed out","messagePattern":"could not retrieve configuration, the server response timed out","errorType":"exception","errorClass":"CCImportError","httpStatus":null,"severity":"error","filePath":"lib/cc/importer/blti_converter.rb","lineNumber":149,"sourceCode":"        obj.each_value { |v| check_for_unescaped_url_properties(v) }\n      when Array\n        obj.each { |o| check_for_unescaped_url_properties(o) }\n      end\n    end\n\n    def check_for_unescaped_url(url)\n      if /(.*[^=]*\\?*=)[^&;]*=/.match?(url)\n        raise CCImportError, I18n.t(:invalid_url_in_xml, \"Invalid url in xml. Ampersands must be escaped.\")\n      end\n    end\n\n    def retrieve_and_convert_blti_url(url)\n      InstrumentTLSCiphers.without_tls_metrics do\n        response = CanvasHttp.get(url, redirect_limit: 10)\n        config_xml = response.body\n        convert_blti_xml(config_xml)\n      rescue Timeout::Error\n        raise CCImportError, I18n.t(:retrieve_timeout, \"could not retrieve configuration, the server response timed out\")\n      end\n    end\n\n    def get_custom_properties(node)\n      props = {}\n      node.children.each do |property|\n        next if property.name == \"text\"\n\n        case property.name\n        when \"property\"\n          props[property[\"name\"]] = property.text.strip\n        when \"options\"\n          props[property[\"name\"]] = get_custom_properties(property)\n        when \"custom\"\n          props[:custom_fields] = get_custom_properties(property)\n        end\n      end\n      props","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/lib/cc/importer/blti_converter.rb#L131-L167","documentation":"retrieve_and_convert_blti_url downloads a BLTI tool configuration over HTTP with CanvasHttp (redirect_limit: 10) and converts it. A Timeout::Error from the network fetch is rescued and re-raised as CCImportError stating the server response timed out, so imports fail fast instead of hanging.","triggerScenarios":"CanvasHttp.get against the tool's configuration URL exceeds the HTTP timeout — the remote server is slow, unreachable, or silently stalling — before convert_blti_xml can run.","commonSituations":"A tool provider's config endpoint is down or overloaded; a firewall blocks outbound requests so the connection hangs; the configured URL points to a host that never responds; network latency spikes in a datacenter.","solutions":["Verify the configuration URL is reachable (curl -v <url>) from the Canvas server, then retry the import","Confirm the tool provider's endpoint is up and responsive, or get an alternative config URL","Check network/firewall/proxy settings on the Canvas host that could stall outbound HTTPS","Retry later if the provider is experiencing an outage"],"exampleFix":"# before (direct fetch, no reachability check)\nconvert_blti_url 'https://unresponsive.example.com/config.xml'\n\n# after (verify endpoint first, then import)\nuri = 'https://tool.example.com/config.xml'\nraise 'config endpoint unreachable' unless Net::HTTP.get_response(URI(uri)).is_a?(Net::HTTPSuccess)\nconvert_blti_url uri","handlingStrategy":"try-catch","validationCode":"resp = Net::HTTP.get_response(URI(url))\nraise 'endpoint unreachable' unless resp.is_a?(Net::HTTPSuccess)","typeGuard":null,"tryCatchPattern":"begin\n  tool = converter.retrieve_and_convert_blti_url(url)\nrescue CCImportError => e\n  if e.message.include?('timed out')\n    flash[:error] = I18n.t('tool_config_unreachable')\n  else\n    raise\n  end\nend","preventionTips":["Curl the config URL from the Canvas host before configuring the tool","Set expectations with the vendor about endpoint availability","Surface a retry path to users instead of failing the whole import","Monitor outbound HTTP timeouts to detect provider outages early"],"tags":["network","http","timeout","lti"],"backgroundTag":"request-timeout","analyzedSha":"1c9f0bb8013ed69c4f2efe11fd483025469b7e6c","analyzedAt":"2026-09-15T20:33:18.891Z","contentChangedAt":"2026-09-15T20:33:18.891Z","schemaVersion":2},"datasetVersion":"2026-09-23T02:17:17.105Z"}