docusealco/docuseal · error · DownloadUtils::UnableToDownload

Error loading: #{uri}

Error message

Error loading: #{uri}

What it means

DownloadUtils.call fetches a remote URL (e.g. attach_url files, webhook-fetched documents) and raises UnableToDownload with 'Error loading: <uri>' when the remote answers HTTP >= 400. It is strictly an HTTP-level failure - the URL was valid enough to request, but the server refused or errored. Scheme/host validation (HTTPS-only, no localhost) happens separately in validate_uri! with its own messages.

Source

Thrown at lib/download_utils.rb:49

    'ip6-allrouters'
  ].freeze

  UnableToDownload = Class.new(StandardError)

  module_function

  def call(url, validate: Docuseal.multitenant?)
    uri = begin
      URI(url)
    rescue URI::Error
      Addressable::URI.parse(url).normalize
    end

    validate_uri!(uri) if validate

    resp = conn(validate:).get(uri)

    raise UnableToDownload, "Error loading: #{uri}" if resp.status >= 400

    resp
  end

  def validate_uri!(uri)
    raise UnableToDownload, "Error loading: #{uri}. Only HTTPS is allowed." if uri.scheme != 'https' ||
                                                                               [443, nil].exclude?(uri.port)
    raise UnableToDownload, "Error loading: #{uri}. Can't download from localhost." if uri.host.in?(LOCALHOSTS)
  end

  def conn(validate: Docuseal.multitenant?)
    Faraday.new do |faraday|
      faraday.response :follow_redirects, callback: lambda { |_, new_env|
        validate_uri!(new_env[:url]) if validate
      }
    end
  end
end

View on GitHub (pinned to 004a22c1c8)

Solutions

  1. From the app host, run a HEAD/GET against the URL to see the exact status the downloader gets.
  2. Fix the URL: refresh the signature, correct permissions, or use a durable location.
  3. If the provider requires auth, serve the file through an authenticated endpoint you control.
  4. For recurring rot, store stable URLs and resolve them to signed links at download time.
Defensive patterns

Strategy: validation

Validate before calling

# pre-flight the URL before handing it to DownloadUtils
resp = Faraday.head(url)
raise UnableToDownload, "Error loading: #{url}" if resp.status >= 400

Try / catch

begin
  DownloadUtils.call(url)
rescue UnableToDownload => e
  Rails.logger.warn(e.message)
  notify_owner_of_failed_attachment(e.message)
end

Prevention

When it happens

Trigger: Passing a file URL that 404s or 403s: expired presigned S3 links, auth-gated assets, hotlink-protected CDNs; provider 5xx during incidents; URLs that redirect to an error page.

Common situations: Presigned links expiring before download; moving a bucket or file without updating stored URLs; providers requiring headers the plain Faraday GET does not send.

Related errors


AI-assisted analysis of docusealco/docuseal@004a22c1c8 (2026-08-21). Data as JSON: /api/errors/2eac9031314b88ec. Report an issue: GitHub.