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 headersView on GitHub (pinned to b5f0abe10e)
Solutions
- Confirm what the URL actually returns from the app host: curl -i <url> and inspect status plus Content-Length
- Fix the remote endpoint to serve the real file bytes with 200 and a body
- 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
- Preflight download URLs with a GET/HEAD and require a non-empty body (or Content-Length > 0)
- Treat endpoints that can legitimately answer 204 as invalid sources for remote-file download
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
- could not download file: #{e.message}
- couldn't parse URL: #{source}
- errors.messages.processing_error
- errors.messages.processing_error
- errors.messages.processing_error
AI-assisted analysis of carrierwaveuploader/carrierwave@b5f0abe10e (2026-08-21).
Data as JSON: /api/errors/46fa53c9a4210575.
Report an issue: GitHub.