carrierwaveuploader/carrierwave · error · CarrierWave::UnknownStorageError
Unknown storage: #{storage}
Error message
Unknown storage: #{storage} What it means
Raised as CarrierWave::UnknownStorageError by CarrierWave::Uploader.configuration#storage when a Symbol is passed that has no entry in storage_engines. By default only :file (CarrierWave::Storage::File) and :fog (CarrierWave::Storage::Fog) are registered; any other symbol — including engines provided by external gems until registered — is rejected at configure time.
Source
Thrown at lib/carrierwave/uploader/configuration.rb:88
# [storage (Symbol, Class)] The storage engine to use for this uploader
#
# === Returns
#
# [Class] the storage engine to be used with this uploader
#
# === Examples
#
# storage :file
# storage CarrierWave::Storage::File
# storage MyCustomStorageEngine
#
def storage(storage = nil)
case storage
when Symbol
if (storage_engine = storage_engines[storage])
self._storage = eval storage_engine
else
raise CarrierWave::UnknownStorageError, "Unknown storage: #{storage}"
end
when nil
# noop
else
self._storage = storage
end
_storage
end
alias_method :storage=, :storage
##
# Sets the cache storage engine to be used when storing cache files with this uploader.
# Same as .storage except for required methods being #cache!(CarrierWave::SanitizedFile),
# #retrieve_from_cache! and #delete_dir!.
#
# === Parameters
#
# [storage (Symbol, Class)] The cache storage engine to use for this uploaderView on GitHub (pinned to b5f0abe10e)
Solutions
- Use a registered symbol: storage :file or storage :fog (fog covers S3/GCS/Rackspace via fog_credentials)
- Register the custom key first: CarrierWave::Uploader::Base.storage_engines[:my_store] = 'MyStore' (or add it via configure) then storage :my_store
- Or pass the class directly: storage CarrierWave::Storage::Fog / storage MyStorageEngine
- If a third-party storage gem is intended, ensure it is in the Gemfile, required, and its registration runs before the uploader class loads
Example fix
# before class ImageUploader < CarrierWave::Uploader::Base storage :s3 # UnknownStorageError: only :file/:fog registered end # after CarrierWave::Uploader::Base.storage_engines[:s3] = 'CarrierWave::Storage::Fog' class ImageUploader < CarrierWave::Uploader::Base storage :s3 # now resolves to CarrierWave::Storage::Fog end
Defensive patterns
Strategy: validation
Validate before calling
def registered_storage?(sym)
CarrierWave::Uploader::Base.storage_engines.key?(sym.to_sym)
end
raise ArgumentError, "unknown storage #{storage}" unless registered_storage?(storage) Type guard
def storage_symbol?(value) value.is_a?(Symbol) && CarrierWave::Uploader::Base.storage_engines.key?(value) end
Prevention
- Register custom engines in an initializer: CarrierWave::Uploader::Base.storage_engines[:my_store] = 'MyStore' before uploaders load
- Prefer passing the storage class itself (storage MyStorage) over symbols for anything beyond :file/:fog
- Boot-time smoke test: call storage on each configured uploader inside a spec so misconfiguration fails in CI, not production
When it happens
Trigger: Writing storage :aws, storage :s3, storage :gcs, storage :qiniu etc. in an uploader or initializer without registering that engine key in CarrierWave::Uploader::Base.storage_engines, or without the gem that registers it being loaded.
Common situations: Copy-pasted uploader examples targeting carrierwave-aws/carrierwave-google-storage style gems while still on plain carrierwave; typos (:File vs :file); gems whose engine registration code was removed in an upgrade; Spring/Zeitwerk loading order hiding the registration.
Related errors
- Need to implement #cache! if you want to use #{self.class.na
- Need to implement #retrieve_from_cache! if you want to use #
- Need to implement #delete_dir! if you want to use #{self.cla
- Need to implement #clean_cache! if you want to use #{self.cl
- could not download file: #{e.message}
AI-assisted analysis of carrierwaveuploader/carrierwave@b5f0abe10e (2026-08-21).
Data as JSON: /api/errors/28a5fb12fda58e99.
Report an issue: GitHub.