instructure/canvas-lms · error · CanvasUnzip::UnknownArchiveType

unknown mime type # for archive #

Error message

unknown mime type #{mime_type} for archive #{File.basename(archive_filename)}

What it means

CanvasUnzip.each_entry raises UnknownArchiveType with this message when neither the file's mime type (via File.mime_type magic detection, with extension fallback) nor the branch logic recognizes it as zip, tar, or gzip-supported archive. The library only supports known archive formats and refuses anything else.

Solutions

  1. Validate the upload's mime type/extension client- and server-side, accepting only zip/tar/tgz before calling CanvasUnzip.
  2. Tell the user the format is unsupported and ask for a zip or tar archive.
  3. Rescue CanvasUnzip::UnknownArchiveType and show a clear 'Unsupported archive type' error instead of a stack trace.
  4. If a legit format (e.g. 7z) is needed, convert it server-side with a tool that supports it before extraction.
  5. Check the host's mime detection (file command/db) if valid .zip files are misdetected.

Example fix

// before
CanvasUnzip.extract_archive(upload_path, dest)
// after
unless upload_path =~ /\.(zip|tar|tgz|tar\.gz)\z/
  return errors.add(:file, "must be a zip or tar archive")
end
CanvasUnzip.extract_archive(upload_path, dest)
Defensive patterns

Strategy: validation

Validate before calling

allowed = %r{\.(zip|tar|tgz|tar\.gz)\z}
raise UnsupportedArchive unless archive_filename.match?(allowed)

Type guard

def supported_archive?(path)
  %w[application/zip application/x-tar application/gzip].include?(File.mime_type(File.open(path)))
end

Try / catch

begin
  CanvasUnzip.extract_archive(path, dest)
rescue CanvasUnzip::UnknownArchiveType => e
  errors.add(:file, "Unsupported archive type. Please upload a .zip or .tar archive.")
  Rails.logger.info("unsupported archive: #{e.message}")
end

Prevention

When it happens

Trigger: Extracting a file that isn't an archive at all (plain text, PDF, image) — often because the upload was never validated; a rare format like 7z, rar, or a mislabeled file whose magic bytes aren't recognized on the host (missing libmagic entries); empty/0-byte files detected as application/octet-stream with a non-archive extension.

Common situations: Users uploading unsupported formats (.7z, .rar) through a course-import or file-upload flow that assumed .zip; OS differences in mime detection producing unusual types; files renamed without changing content; empty file uploads.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15). Data as JSON: /api/errors/f579a3376e6c5b9d. Report an issue: GitHub.

Appendix: source

Thrown at gems/canvas_unzip/lib/canvas_unzip.rb:151

      Zip::File.open(file) do |zipfile|
        zipfile.entries.each_with_index do |zip_entry, index|
          yield(Entry.new(zip_entry), index)
        end
      end
    when "application/x-tar"
      index = 0
      begin
        Gem::Package::TarReader.new(file).each do |tar_entry|
          next if tar_entry.header.typeflag == "x"

          yield(Entry.new(tar_entry), index)
          index += 1
        end
      rescue Gem::Package::TarInvalidError
        raise UnknownArchiveType, "invalid tar"
      end
    else
      raise UnknownArchiveType, "unknown mime type #{mime_type} for archive #{File.basename(archive_filename)}"
    end
  end

  def self.compute_uncompressed_size(archive_filename)
    total_size = 0
    each_entry(archive_filename) { |entry, _index| total_size += entry.size }
    total_size
  end

  class Entry
    attr_reader :entry, :type

    def initialize(entry)
      case entry
      when Zip::Entry
        @type = :zip
      when Gem::Package::TarReader::Entry
        @type = :tar

View on GitHub (pinned to 1c9f0bb801)