carrierwaveuploader/carrierwave · error · CarrierWave::IntegrityError
errors.messages.content_type_denylist_error
Error message
errors.messages.content_type_denylist_error
What it means
Raised as CarrierWave::IntegrityError when check_content_type_denylist! finds the uploaded file's content type matches an entry in the deprecated content_type_denylist (matching is unanchored regex: content_type =~ /#{item}/). Note the method itself warns that denylisting is deprecated for security reasons and recommends content_type_allowlist; it also still honors the older content_type_blacklist with a warning.
Source
Thrown at lib/carrierwave/uploader/content_type_denylist.rb:51
private
def check_content_type_denylist!(new_file)
denylist = content_type_denylist
if !denylist && respond_to?(:content_type_blacklist) && content_type_blacklist
CarrierWave.deprecator.warn "#content_type_blacklist is deprecated, use #content_type_denylist instead." unless instance_variable_defined?(:@content_type_blacklist_warned)
@content_type_blacklist_warned = true
denylist = content_type_blacklist
end
return unless denylist
CarrierWave.deprecator.warn "Use of #content_type_denylist is deprecated for the security reason, use #content_type_allowlist instead to explicitly state what are safe to accept" unless instance_variable_defined?(:@content_type_denylist_warned)
@content_type_denylist_warned = true
content_type = new_file.content_type
if denylisted_content_type?(denylist, content_type)
raise CarrierWave::IntegrityError, I18n.translate(:"errors.messages.content_type_denylist_error",
content_type: content_type, default: :"errors.messages.content_type_blacklist_error")
end
end
def denylisted_content_type?(denylist, content_type)
Array(denylist).any? do |item|
item = Regexp.quote(item) if item.class != Regexp
content_type =~ /#{item}/
end
end
end # ContentTypeDenylist
end # Uploader
end # CarrierWave
View on GitHub (pinned to b5f0abe10e)
Solutions
- Replace content_type_denylist with an explicit content_type_allowlist of the types you actually accept
- Rescue CarrierWave::IntegrityError and render a validation message instead of a 500
- If you must temporarily keep the denylist, remember matching is substring-based — anchor regexes deliberately
Example fix
# before class DocUploader < CarrierWave::Uploader::Base def content_type_denylist; ['application/x-msdownload']; end # IntegrityError + deprecation end # after class DocUploader < CarrierWave::Uploader::Base def content_type_allowlist; %w(application/pdf image/png); end end
Defensive patterns
Strategy: validation
Validate before calling
ALLOWED = %w[application/pdf image/png].freeze
def content_type_allowed?(type)
ALLOWED.any? { |a| type.to_s.start_with?(a) }
end Type guard
def content_type_allowed?(type)
ALLOWED.any? { |a| type.to_s.start_with?(a) }
end Try / catch
begin record.doc = params[:doc] record.save! rescue CarrierWave::IntegrityError record.errors.add(:doc, :content_type_not_allowed) render :new end
Prevention
- Replace content_type_denylist/content_type_blacklist with an explicit content_type_allowlist — denylists trust spoofable client-reported types
- Rescue CarrierWave::IntegrityError at the assignment site for friendly errors
- Remember denylist entries match as unanchored regex substrings when writing any temporary entries
When it happens
Trigger: Declaring content_type_denylist ['text/html', 'application/php'] and uploading a file whose reported type matches any entry as a substring; or still defining content_type_blacklist from pre-migration code, which routes into the same check.
Common situations: Apps migrated from old whitelist/blacklist-named methods that kept the blacklist semantics; security reviews flagging that content types can be spoofed client-side, since denylisting trusts the browser-reported type.
Related errors
- errors.messages.content_type_allowlist_error
- errors.messages.min_width_error
- errors.messages.max_width_error
- errors.messages.min_height_error
- errors.messages.max_height_error
AI-assisted analysis of carrierwaveuploader/carrierwave@b5f0abe10e (2026-08-21).
Data as JSON: /api/errors/49c8df5067ac130a.
Report an issue: GitHub.