carrierwaveuploader/carrierwave · error · CarrierWave::IntegrityError
errors.messages.extension_allowlist_error
Error message
errors.messages.extension_allowlist_error
What it means
CarrierWave raises CarrierWave::IntegrityError with this message from the `before :cache` callback `check_extension_allowlist!` when the file being cached has an extension that is not in the uploader's `extension_allowlist`. The check runs automatically on every cache operation (i.e., when a file is assigned to the mounted uploader attribute), before the file is ever stored. Comparison is case-insensitive and each allowlist item (String or Regexp) is automatically anchored with \A...\z, so partial matches never pass. If the uploader only defines the deprecated `extension_whitelist`, it is used as a fallback with a deprecation warning.
Source
Thrown at lib/carrierwave/uploader/extension_allowlist.rb:52
def extension_allowlist
end
private
def check_extension_allowlist!(new_file)
allowlist = extension_allowlist
if !allowlist && respond_to?(:extension_whitelist) && extension_whitelist
CarrierWave.deprecator.warn "#extension_whitelist is deprecated, use #extension_allowlist instead." unless instance_variable_defined?(:@extension_whitelist_warned)
@extension_whitelist_warned = true
allowlist = extension_whitelist
end
return unless allowlist
extension = new_file.extension.to_s
if !allowlisted_extension?(allowlist, extension)
# Look for whitelist first, then fallback to allowlist
raise CarrierWave::IntegrityError, I18n.translate(:"errors.messages.extension_allowlist_error", extension: new_file.extension.inspect,
allowed_types: Array(allowlist).join(", "), default: :"errors.messages.extension_whitelist_error")
end
end
def allowlisted_extension?(allowlist, extension)
downcase_extension = extension.downcase
Array(allowlist).any? { |item| downcase_extension =~ /\A#{item}\z/i }
end
end # ExtensionAllowlist
end # Uploader
end # CarrierWave
View on GitHub (pinned to b5f0abe10e)
Solutions
- Add the missing extension to `extension_allowlist` in your uploader, e.g. change `%w(jpg png)` to `%w(jpg jpeg png)`.
- Check the actual extension the file carries (`File.extname(original_filename)`), including no-extension and double-extension files, before editing the list.
- Write list items without dots or globs; if using Regexps remember they are auto-anchored with \A/\z, so spell the full extension (e.g. `/jpe?g/`, not `/j/`).
- If some uploader should accept anything, return nil from `extension_allowlist` (the callback returns early when the list is nil).
- Wrap assignment in the controller with `rescue CarrierWave::IntegrityError` and surface `e.message` as a validation error.
Example fix
# before
class AvatarUploader < CarrierWave::Uploader::Base
def extension_allowlist
%w[jpg png]
end
end
# user uploads "photo.jpeg" => CarrierWave::IntegrityError: extension_allowlist_error
# after
class AvatarUploader < CarrierWave::Uploader::Base
def extension_allowlist
%w[jpg jpeg png]
end
end Defensive patterns
Strategy: validation
Validate before calling
ALLOWED = %w[jpg jpeg png].freeze
ext = File.extname(uploaded_io.original_filename.to_s).delete_prefix('.').downcase
unless ALLOWED.any? { |a| ext =~ /\A#{a}\z/i }
# reject before assigning to the model attribute / calling cache!
errors.add(:avatar, "#{ext.inspect} is not an allowed file type")
end Try / catch
begin user.avatar = params[:avatar] # triggers cache! and the allowlist check rescue CarrierWave::IntegrityError => e # e.message is the localized extension_allowlist_error flash.now[:alert] = e.message render :edit, status: :unprocessable_entity end
Prevention
- Keep extension_allowlist in one constant shared by client and server so both sides agree.
- Test the uploader with every extension users may submit, including uppercase and double extensions.
- Write list items bare (jpg, not .jpg or *.jpg) and full-length Regexps — items are auto-anchored with \\A/\\z.
- In Rails, rescue_from CarrierWave::IntegrityError in the controller to turn integrity failures into 422s instead of 500s.
When it happens
Trigger: Calling `uploader.cache!(file)` or assigning an uploaded file to a `mount_uploader` attribute where `File.extname` of the file is not matched by any item in `extension_allowlist`. Concrete cases: uploader defines `%w(jpg png)` and the user uploads `photo.jpeg`; a Regexp item like `/j/` fails for `jpeg` because it is anchored to `/\Aj\z/i`; the file has no extension at all (empty string matches nothing); the allowlist contains a leading dot (`.jpg`) so it only matches a literal '.jpg' extension.
Common situations: Apps migrating from the deprecated `extension_whitelist` to `extension_allowlist` (CarrierWave 2.x rename) and missing a variant like `jpeg` vs `jpg`; allowlists written with dots or globs (`*.jpg`, `.jpg`) copied from other libraries; double extensions (`image.tar.gz` — the extension is only `gz`); case handled by the matcher, but uppercase items like 'JPG' also work since matching is /i; expected-integrity failures surfacing as exceptions in controllers instead of validation messages.
Related errors
- errors.messages.extension_denylist_error
- errors.messages.min_size_error
- errors.messages.max_size_error
- Version #{version} doesn't exist!
- could not download file: #{e.message}
AI-assisted analysis of carrierwaveuploader/carrierwave@b5f0abe10e (2026-08-21).
Data as JSON: /api/errors/62e098b9e6453bf2.
Report an issue: GitHub.