{"record":{"id":"3b071ceefca402a2","repo":"carrierwaveuploader/carrierwave","slug":"could-not-download-file-e-message","errorCode":null,"errorMessage":"could not download file: #{e.message}","messagePattern":"could not download file: #(.+?)","errorType":"exception","errorClass":"CarrierWave::DownloadError","httpStatus":null,"severity":"error","filePath":"lib/carrierwave/downloader/base.rb","lineNumber":53,"sourceCode":"            if ::SsrfFilter::VERSION.to_f < 1.1\n              response = SsrfFilter.get(uri, headers: headers) do |req|\n                request = req\n              end\n            else\n              response = SsrfFilter.get(uri, headers: headers, request_proc: ->(req) { request = req }) do |res|\n                res.body # ensure to read body\n              end\n            end\n            response.uri = request.uri\n            response.value\n          end\n        rescue StandardError => e\n          if @current_download_retry_count < @uploader.download_retry_count\n            @current_download_retry_count += 1\n            sleep @uploader.download_retry_wait_time\n            retry\n          else\n            raise CarrierWave::DownloadError, \"could not download file: #{e.message}\"\n          end\n        end\n        CarrierWave::Downloader::RemoteFile.new(response)\n      end\n\n      ##\n      # Processes the given URL by parsing it, and escaping if necessary. Public to allow overriding.\n      #\n      # === Parameters\n      #\n      # [url (String)] The URL where the remote file is stored\n      #\n      def process_uri(source)\n        uri = Addressable::URI.parse(source)\n        uri.host = uri.normalized_host\n        # Perform decode first, as the path is likely to be already encoded\n        uri.path = encode_path(decode_uri(uri.path)) if uri.path =~ CarrierWave::Utilities::Uri::PATH_UNSAFE\n        uri.query = encode_non_ascii(uri.query) if uri.query","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/carrierwaveuploader/carrierwave/blob/b5f0abe10ecf6500309fc83e0e8969cf57ba690e/lib/carrierwave/downloader/base.rb#L35-L71","documentation":"Raised as CarrierWave::DownloadError by CarrierWave::Downloader::Base#download! when the underlying Net::HTTP request to a remote URL fails for any reason (DNS failure, timeout, SSL error, or a non-2xx HTTP status, which response.value turns into an error). The downloader retries the request up to uploader.download_retry_count times (default 0) waiting download_retry_wait_time seconds (default 5) between attempts, then gives up and wraps the last exception message in this error.","triggerScenarios":"Calling uploader.download!('http://...') or assigning a remote URL attribute (e.g. user.avatar = 'http://example.com/photo.jpg' with remote_avatar_url form fields) where the host is unreachable, the URL returns 404/500 (response.value raises on non-2xx), the TLS certificate is invalid, or the connection times out after the retry budget is exhausted.","commonSituations":"Apps that let users upload 'avatar by URL'; the linked server is down or blocks the request; a redirect chain ends in an error; using default config.download_retry_count = 0 so even one transient network hiccup surfaces as this error.","solutions":["Verify the URL actually returns the file with 2xx status (curl -I <url>) and fix or reject it","Rescue CarrierWave::DownloadError where you assign the remote URL and show a friendly validation message","Enable retries in an initializer: config.download_retry_count = 3 and config.download_retry_wait_time = 5","For persistent failures, check DNS/firewall/proxy egress rules and TLS certificate validity from the app host"],"exampleFix":"# before\nuser.avatar = params[:avatar_url] # raises CarrierWave::DownloadError on bad URL\n\n# after\nbegin\n  user.avatar = params[:avatar_url]\nrescue CarrierWave::DownloadError => e\n  user.errors.add(:avatar_url, e.message)\nend","handlingStrategy":"try-catch","validationCode":"require 'net/http'\ndef downloadable?(url, timeout: 5)\n  uri = URI.parse(url)\n  return false unless uri.is_a?(URI::HTTP)\n  res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https', open_timeout: timeout, read_timeout: timeout) { |http| http.head(uri.request_uri) }\n  res.is_a?(Net::HTTPSuccess) && (res['content-length'].nil? || res['content-length'].to_i > 0)\nrescue StandardError\n  false\nend\nreturn unless downloadable?(params[:avatar_url])","typeGuard":null,"tryCatchPattern":"begin\n  record.avatar = params[:avatar_url] # or uploader.download!(url)\nrescue CarrierWave::DownloadError => e\n  record.errors.add(:avatar_url, :download_failed, message: e.message)\nend","preventionTips":["Wrap every remote-URL assignment in rescue CarrierWave::DownloadError and map it to a form error","Configure config.download_retry_count and download_retry_wait_time for transient network resilience instead of the 0-retry default","Preflight user-supplied URLs with a HEAD request (status + content-length) before storing them"],"tags":["carrierwave","network","download","remote-file","retry"],"backgroundTag":"http-download-failed","analyzedSha":"b5f0abe10ecf6500309fc83e0e8969cf57ba690e","analyzedAt":"2026-08-21T18:07:27.715Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}