carrierwaveuploader/carrierwave · error · CarrierWave::IntegrityError

errors.messages.extension_denylist_error

Error message

errors.messages.extension_denylist_error

What it means

CarrierWave raises CarrierWave::IntegrityError with this message from the `before :cache` callback `check_extension_denylist!` when the file being cached has an extension that appears in the uploader's `extension_denylist`. The match is anchored (\A...\z) and case-insensitive per item. CarrierWave itself warns that denylists are the wrong security tool — using `extension_allowlist` to state what is safe is the recommended pattern, and merely defining `extension_denylist` emits a deprecation warning.

Source

Thrown at lib/carrierwave/uploader/extension_denylist.rb:54

    private

      def check_extension_denylist!(new_file)
        denylist = extension_denylist
        if !denylist && respond_to?(:extension_blacklist) && extension_blacklist
          CarrierWave.deprecator.warn "#extension_blacklist is deprecated, use #extension_denylist instead." unless instance_variable_defined?(:@extension_blacklist_warned)
          @extension_blacklist_warned = true
          denylist = extension_blacklist
        end

        return unless denylist

        CarrierWave.deprecator.warn "Use of #extension_denylist is deprecated for the security reason, use #extension_allowlist instead to explicitly state what are safe to accept" unless instance_variable_defined?(:@extension_denylist_warned)
        @extension_denylist_warned = true

        extension = new_file.extension.to_s
        if denylisted_extension?(denylist, extension)
          raise CarrierWave::IntegrityError, I18n.translate(:"errors.messages.extension_denylist_error", extension: new_file.extension.inspect,
                                                            prohibited_types: Array(extension_denylist).join(", "), default: :"errors.messages.extension_blacklist_error")
        end
      end

      def denylisted_extension?(denylist, extension)
        Array(denylist).any? { |item| extension =~ /\A#{item}\z/i }
      end
    end
  end
end

View on GitHub (pinned to b5f0abe10e)

Solutions

  1. Replace `extension_denylist` with an explicit `extension_allowlist` of the formats the app actually accepts — this is what CarrierWave recommends and removes the deprecation warning.
  2. If the extension was denied by mistake, remove it from the denylist (or keep it and convert the legitimate use case to another upload path).
  3. Wrap the assignment in `rescue CarrierWave::IntegrityError` and report the message (`extension: ... prohibited_types: ...`) to the user instead of a 500.
  4. Rename the deprecated `extension_blacklist` to `extension_denylist` first if you are mid-migration, then move to the allowlist.

Example fix

# before
class DocumentUploader < CarrierWave::Uploader::Base
  def extension_denylist
    %w[exe bat sh]
  end
end
# uploading "invoice.exe" => CarrierWave::IntegrityError: extension_denylist_error

# after (recommended: explicit allowlist)
class DocumentUploader < CarrierWave::Uploader::Base
  def extension_allowlist
    %w[pdf doc docx]
  end
end
Defensive patterns

Strategy: validation

Validate before calling

# Deny checks only answer "is this on the bad list" — prefer an allowlist at the boundary:
ALLOWED = %w[pdf doc docx].freeze
ext = File.extname(uploaded_io.original_filename.to_s).delete_prefix('.').downcase
return false if ext.empty?
allowed = ALLOWED.any? { |a| ext =~ /\A#{a}\z/i }

Try / catch

begin
  user.document = params[:document]
rescue CarrierWave::IntegrityError => e
  # e.message carries the denylist (prohibited_types) — avoid echoing the raw list to users; substitute your own copy
  errors.add(:document, :invalid_extension)
end

Prevention

When it happens

Trigger: Calling `uploader.cache!(file)` or assigning an uploaded file to a `mount_uploader` attribute when the file's extension equals one of the items in `extension_denylist` (e.g. denylist `%w[exe bat]` and the upload is `setup.exe`). Also triggered via the deprecated `extension_blacklist` fallback when `extension_denylist` is not defined.

Common situations: Legacy apps still on `extension_blacklist`/`extension_denylist` after upgrading CarrierWave 2.x (rename plus the security deprecation warning); denylists that block executables but let dangerous web content (`.html`, `.svg` with scripts) through; uploads blocked in staging because the denylist was copied from another app and includes a format the business actually needs (e.g. `pdf`).

Related errors


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