instructure/canvas-lms · error · Attachment::OverQuotaError

Zip file would exceed quota limit

Error message

Zip file would exceed quota limit

What it means

validate_against in lib/unzip_attachment.rb:287 raises Attachment::OverQuotaError when the zip's nominal total uncompressed size plus the context's current quota usage would exceed the context quota. Canvas checks this pre-extraction using Attachment.get_quota so oversized zips are rejected immediately.

Solutions

  1. Free up file quota in the target course/user (delete unneeded files) before uploading
  2. Upload a smaller zip or upload files individually as space allows
  3. Ask an admin to raise the quota for the course/user/account
  4. Check remaining space via the files page quota indicator before attempting the upload

Example fix

// before
UnzipAttachment.process(course, 'big_media_20gb.zip') # quota_used + 20GB > quota
// after
# delete unused files to free space, or request quota increase, then retry upload
Defensive patterns

Strategy: try-catch

Validate before calling

quota = Attachment.get_quota(context)
raise OverQuotaError if quota[:quota] > 0 && quota[:quota_used] + zip_total_size > quota[:quota]

Try / catch

begin
  UnzipAttachment.process(context, zip)
rescue Attachment::OverQuotaError => e
  flash[:error] = e.message
end

Prevention

When it happens

Trigger: extracting/unzipping into a course or user context where quota_hash[:quota_used] + total_size > quota_hash[:quota] and quota is non-zero; typical call sites are Attachment.zip uploads or course copy/import unzipping into a files area.

Common situations: Instructor near their course file quota uploads a large media zip; importing a course export archive bigger than remaining space; account with small quota configured receiving bulk content uploads.

Related errors


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

Appendix: source

Thrown at lib/unzip_attachment.rb:287

    @filename = filename
    @paths = []
    @file_count = 0
    @total_size = 0
    @quota_remaining = nil
    process!
  end

  def validate_against(context)
    if file_count > MAX_FILE_COUNT
      raise ArgumentError, "Zip File cannot have more than #{MAX_FILE_COUNT} entries"
    end

    # check whether the nominal size of the zip's contents would exceed
    # quota, and reject the zip immediately if so
    quota_hash = Attachment.get_quota(context)
    if quota_hash[:quota] > 0
      if (quota_hash[:quota_used] + total_size) > quota_hash[:quota]
        raise Attachment::OverQuotaError, "Zip file would exceed quota limit"
      end

      @quota_remaining = quota_hash[:quota] - quota_hash[:quota_used]
    end
  end

  # since the central directory can lie, track quota during extraction as well
  # to prevent zip bomb denial-of-service attacks
  def charge_quota(size)
    return if @quota_remaining.nil?
    if size > @quota_remaining
      raise Attachment::OverQuotaError, "Zip contents exceed course quota limit"
    end

    @quota_remaining -= size
  end

  def paths_with_positions(base)

View on GitHub (pinned to 1c9f0bb801)