instructure/canvas-lms · error · CCImportError

could not retrieve configuration, the server response timed…

Error message

could not retrieve configuration, the server response timed out

What it means

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.

Solutions

  1. Verify the configuration URL is reachable (curl -v <url>) from the Canvas server, then retry the import
  2. Confirm the tool provider's endpoint is up and responsive, or get an alternative config URL
  3. Check network/firewall/proxy settings on the Canvas host that could stall outbound HTTPS
  4. Retry later if the provider is experiencing an outage

Example fix

# before (direct fetch, no reachability check)
convert_blti_url 'https://unresponsive.example.com/config.xml'

# after (verify endpoint first, then import)
uri = 'https://tool.example.com/config.xml'
raise 'config endpoint unreachable' unless Net::HTTP.get_response(URI(uri)).is_a?(Net::HTTPSuccess)
convert_blti_url uri
Defensive patterns

Strategy: try-catch

Validate before calling

resp = Net::HTTP.get_response(URI(url))
raise 'endpoint unreachable' unless resp.is_a?(Net::HTTPSuccess)

Try / catch

begin
  tool = converter.retrieve_and_convert_blti_url(url)
rescue CCImportError => e
  if e.message.include?('timed out')
    flash[:error] = I18n.t('tool_config_unreachable')
  else
    raise
  end
end

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.

Related errors


AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15). Data as JSON: /api/errors/b49492565545852c. Report an issue: GitHub.

Appendix: source

Thrown at lib/cc/importer/blti_converter.rb:149

        obj.each_value { |v| check_for_unescaped_url_properties(v) }
      when Array
        obj.each { |o| check_for_unescaped_url_properties(o) }
      end
    end

    def check_for_unescaped_url(url)
      if /(.*[^=]*\?*=)[^&;]*=/.match?(url)
        raise CCImportError, I18n.t(:invalid_url_in_xml, "Invalid url in xml. Ampersands must be escaped.")
      end
    end

    def retrieve_and_convert_blti_url(url)
      InstrumentTLSCiphers.without_tls_metrics do
        response = CanvasHttp.get(url, redirect_limit: 10)
        config_xml = response.body
        convert_blti_xml(config_xml)
      rescue Timeout::Error
        raise CCImportError, I18n.t(:retrieve_timeout, "could not retrieve configuration, the server response timed out")
      end
    end

    def get_custom_properties(node)
      props = {}
      node.children.each do |property|
        next if property.name == "text"

        case property.name
        when "property"
          props[property["name"]] = property.text.strip
        when "options"
          props[property["name"]] = get_custom_properties(property)
        when "custom"
          props[:custom_fields] = get_custom_properties(property)
        end
      end
      props

View on GitHub (pinned to 1c9f0bb801)