{"record":{"id":"62e098b9e6453bf2","repo":"carrierwaveuploader/carrierwave","slug":"errors-messages-extension-allowlist-error","errorCode":null,"errorMessage":"errors.messages.extension_allowlist_error","messagePattern":"errors\\.messages\\.extension_allowlist_error","errorType":"exception","errorClass":"CarrierWave::IntegrityError","httpStatus":null,"severity":"error","filePath":"lib/carrierwave/uploader/extension_allowlist.rb","lineNumber":52,"sourceCode":"      def extension_allowlist\n      end\n\n    private\n\n      def check_extension_allowlist!(new_file)\n        allowlist = extension_allowlist\n        if !allowlist && respond_to?(:extension_whitelist) && extension_whitelist\n          CarrierWave.deprecator.warn \"#extension_whitelist is deprecated, use #extension_allowlist instead.\" unless instance_variable_defined?(:@extension_whitelist_warned)\n          @extension_whitelist_warned = true\n          allowlist = extension_whitelist\n        end\n\n        return unless allowlist\n\n        extension = new_file.extension.to_s\n        if !allowlisted_extension?(allowlist, extension)\n          # Look for whitelist first, then fallback to allowlist\n          raise CarrierWave::IntegrityError, I18n.translate(:\"errors.messages.extension_allowlist_error\", extension: new_file.extension.inspect,\n                                                            allowed_types: Array(allowlist).join(\", \"), default: :\"errors.messages.extension_whitelist_error\")\n        end\n      end\n\n      def allowlisted_extension?(allowlist, extension)\n        downcase_extension = extension.downcase\n        Array(allowlist).any? { |item| downcase_extension =~ /\\A#{item}\\z/i }\n      end\n    end # ExtensionAllowlist\n  end # Uploader\nend # CarrierWave\n","sourceCodeStart":34,"sourceCodeEnd":64,"githubUrl":"https://github.com/carrierwaveuploader/carrierwave/blob/b5f0abe10ecf6500309fc83e0e8969cf57ba690e/lib/carrierwave/uploader/extension_allowlist.rb#L34-L64","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before\nclass AvatarUploader < CarrierWave::Uploader::Base\n  def extension_allowlist\n    %w[jpg png]\n  end\nend\n# user uploads \"photo.jpeg\" => CarrierWave::IntegrityError: extension_allowlist_error\n\n# after\nclass AvatarUploader < CarrierWave::Uploader::Base\n  def extension_allowlist\n    %w[jpg jpeg png]\n  end\nend","handlingStrategy":"validation","validationCode":"ALLOWED = %w[jpg jpeg png].freeze\n\next = File.extname(uploaded_io.original_filename.to_s).delete_prefix('.').downcase\nunless ALLOWED.any? { |a| ext =~ /\\A#{a}\\z/i }\n  # reject before assigning to the model attribute / calling cache!\n  errors.add(:avatar, \"#{ext.inspect} is not an allowed file type\")\nend","typeGuard":null,"tryCatchPattern":"begin\n  user.avatar = params[:avatar]   # triggers cache! and the allowlist check\nrescue CarrierWave::IntegrityError => e\n  # e.message is the localized extension_allowlist_error\n  flash.now[:alert] = e.message\n  render :edit, status: :unprocessable_entity\nend","preventionTips":["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."],"tags":["carrierwave","ruby","file-upload","extension-validation","integrity-error"],"backgroundTag":"file-extension-rejected","analyzedSha":"b5f0abe10ecf6500309fc83e0e8969cf57ba690e","analyzedAt":"2026-08-21T18:07:27.715Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}