instructure/canvas-lms · error · CanvasUnzip::UnknownArchiveType
invalid tar
Error message
invalid tar
What it means
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.
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.
Example fix
// before
CanvasUnzip.extract_archive(path, dest) # raises UnknownArchiveType
// after
begin
CanvasUnzip.extract_archive(path, dest)
rescue CanvasUnzip::UnknownArchiveType => e
raise ImportFailure, "Corrupt or invalid archive: #{e.message}"
end Defensive patterns
Strategy: validation
Validate before calling
unless system("tar", "-tf", path, out: File::NULL, err: File::NULL)
raise CorruptArchive, "#{path} is not a valid tar"
end Type guard
def intact_archive?(uploaded, stored_path) File.size(stored_path) == uploaded.size end
Try / catch
begin
CanvasUnzip.extract_archive(path, dest)
rescue CanvasUnzip::UnknownArchiveType => e
raise CorruptArchiveError, "Archive is corrupt: #{e.message}"
end Prevention
- Verify downloaded/stored file sizes match uploads
- Validate archives at ingest time
- Reject truncated or partial transfers
- Rescue UnknownArchiveType to show friendly messages
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/4315321f6e8495b1.
Report an issue: GitHub.
Appendix: source
Thrown at gems/canvas_unzip/lib/canvas_unzip.rb:148
case mime_type
when "application/zip"
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::EntryView on GitHub (pinned to 1c9f0bb801)