{"record":{"id":"4315321f6e8495b1","repo":"instructure/canvas-lms","slug":"invalid-tar","errorCode":null,"errorMessage":"invalid tar","messagePattern":"invalid tar","errorType":"exception","errorClass":"CanvasUnzip::UnknownArchiveType","httpStatus":null,"severity":"error","filePath":"gems/canvas_unzip/lib/canvas_unzip.rb","lineNumber":148,"sourceCode":"\n    case mime_type\n    when \"application/zip\"\n      Zip::File.open(file) do |zipfile|\n        zipfile.entries.each_with_index do |zip_entry, index|\n          yield(Entry.new(zip_entry), index)\n        end\n      end\n    when \"application/x-tar\"\n      index = 0\n      begin\n        Gem::Package::TarReader.new(file).each do |tar_entry|\n          next if tar_entry.header.typeflag == \"x\"\n\n          yield(Entry.new(tar_entry), index)\n          index += 1\n        end\n      rescue Gem::Package::TarInvalidError\n        raise UnknownArchiveType, \"invalid tar\"\n      end\n    else\n      raise UnknownArchiveType, \"unknown mime type #{mime_type} for archive #{File.basename(archive_filename)}\"\n    end\n  end\n\n  def self.compute_uncompressed_size(archive_filename)\n    total_size = 0\n    each_entry(archive_filename) { |entry, _index| total_size += entry.size }\n    total_size\n  end\n\n  class Entry\n    attr_reader :entry, :type\n\n    def initialize(entry)\n      case entry\n      when Zip::Entry","sourceCodeStart":130,"sourceCodeEnd":166,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/gems/canvas_unzip/lib/canvas_unzip.rb#L130-L166","documentation":"CanvasUnzip.each_entry raises UnknownArchiveType \"invalid tar\" when the file was detected as a tar archive (via file magic or extension) but Gem::Package::TarReader raises TarInvalidError while reading entries — the tar structure is corrupt, truncated, or not really a tar despite the mime type.","triggerScenarios":"Uploading a truncated tar (partial download/aborted transfer); a gzip that decompresses to garbage but was detected as tar; concatenated or non-USTAR tar variants Gem can't parse; renamed files (e.g. a .txt renamed to .tar.gz) that mime detection still guesses as tar.","commonSituations":"Course import/export content packages that were cut off; users renaming arbitrary files to .tar to bypass upload checks; storage layer returning partial content; old/broken tars produced by nonstandard tools.","solutions":["Regenerate or re-upload the archive — the file itself is corrupt and cannot be salvaged.","Validate the archive at upload time (tar -tf / Archive integrity check) and reject bad files early.","Check file size vs stored size to detect truncated downloads from storage/S3.","Verify mime detection isn't fooled: fall back on real content sniffing and reject files with mismatched extension/content.","Wrap extraction with rescue CanvasUnzip::UnknownArchiveType to surface a friendly 'corrupt archive' message to users."],"exampleFix":"// before\nCanvasUnzip.extract_archive(path, dest) # raises UnknownArchiveType\n// after\nbegin\n  CanvasUnzip.extract_archive(path, dest)\nrescue CanvasUnzip::UnknownArchiveType => e\n  raise ImportFailure, \"Corrupt or invalid archive: #{e.message}\"\nend","handlingStrategy":"validation","validationCode":"unless system(\"tar\", \"-tf\", path, out: File::NULL, err: File::NULL)\n  raise CorruptArchive, \"#{path} is not a valid tar\"\nend","typeGuard":"def intact_archive?(uploaded, stored_path)\n  File.size(stored_path) == uploaded.size\nend","tryCatchPattern":"begin\n  CanvasUnzip.extract_archive(path, dest)\nrescue CanvasUnzip::UnknownArchiveType => e\n  raise CorruptArchiveError, \"Archive is corrupt: #{e.message}\"\nend","preventionTips":["Verify downloaded/stored file sizes match uploads","Validate archives at ingest time","Reject truncated or partial transfers","Rescue UnknownArchiveType to show friendly messages"],"tags":["tar","corrupt-file","archive","upload"],"backgroundTag":"invalid-argument-format","analyzedSha":"1c9f0bb8013ed69c4f2efe11fd483025469b7e6c","analyzedAt":"2026-09-15T20:33:18.891Z","contentChangedAt":"2026-09-15T20:33:18.891Z","schemaVersion":2},"datasetVersion":"2026-09-23T02:17:17.105Z"}