carrierwaveuploader/carrierwave · error · CarrierWave::DownloadError

could not download file: No Content

Error message

could not download file: No Content

What it means

Raised as CarrierWave::DownloadError by CarrierWave::Downloader::RemoteFile#initialize when the wrapped Net::HTTPResponse has a nil body. The downloader only guards HTTP status via response.value; some 2xx responses (204 No Content, 304 Not Modified) succeed that check yet legally carry no body, and RemoteFile refuses to wrap a bodyless response.

Source

Thrown at lib/carrierwave/downloader/remote_file.rb:12

module CarrierWave
  module Downloader
    class RemoteFile
      attr_reader :file, :uri

      def initialize(file)
        case file
        when String
          @file = StringIO.new(file)
        when Net::HTTPResponse
          body = file.body
          raise CarrierWave::DownloadError, 'could not download file: No Content' if body.nil?

          @file = StringIO.new(body)
          @content_type = file.content_type
          @headers = file
          @uri = file.uri
        else
          @file = file
          @content_type = file.content_type
          @headers = file.meta
          @uri = file.base_uri
        end
      end

      def content_type
        @content_type || 'application/octet-stream'
      end

      def headers

View on GitHub (pinned to b5f0abe10e)

Solutions

  1. Confirm what the URL actually returns from the app host: curl -i <url> and inspect status plus Content-Length
  2. Fix the remote endpoint to serve the real file bytes with 200 and a body
  3. If empty responses are expected, rescue CarrierWave::DownloadError and treat it as an invalid URL

Example fix

# before
uploader.download! url # raises 'could not download file: No Content'

# after
begin
  uploader.download! url
rescue CarrierWave::DownloadError => e
  raise if e.message !~ /No Content/
  errors.add(:url, 'returned no content')
end
Defensive patterns

Strategy: validation

Validate before calling

require 'net/http'

def url_serves_body?(url)
  uri = URI.parse(url)
  res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') { |http| http.get(uri.request_uri) }
  res.is_a?(Net::HTTPSuccess) && !res.body.nil? && !res.body.empty?
rescue StandardError
  false
end

Try / catch

begin
  uploader.download!(url)
rescue CarrierWave::DownloadError => e
  if e.message =~ /No Content/
    errors.add(:url, 'returned an empty response')
  else
    raise
  end
end

Prevention

When it happens

Trigger: uploader.download!('http://...') where the endpoint answers 204 No Content or 304 Not Modified (e.g. a cache hit, a HEAD-ish endpoint, or an API route returning empty 2xx instead of the file bytes). The status passes response.value (it is 2xx) but file.body is nil, so this error fires.

Common situations: Pointing the remote-file URL at an API endpoint or CDN edge that returns an empty 2xx under some conditions; a misconfigured server returning 204 for what should be a file download; broken presigned URLs that redirect to an empty response.

Related errors


AI-assisted analysis of carrierwaveuploader/carrierwave@b5f0abe10e (2026-08-21). Data as JSON: /api/errors/46fa53c9a4210575. Report an issue: GitHub.