instructure/canvas-lms · warning
[LocalTextExtractor] Unsupported MIME type: #
Error message
[LocalTextExtractor] Unsupported MIME type: #{attachment.mimetype} What it means
FileTextExtractionService's local text extractor only handles 'pdf' and 'docx' MIME types; for any other mimetype it logs '[LocalTextExtractor] Unsupported MIME type' and returns Result.new("", false) — an empty, failed extraction, not an exception. It signals that the local extraction path cannot process the attachment's file type.
Solutions
- Check attachment.mimetype before invoking the extractor and skip/route unsupported types to an appropriate extraction backend.
- Normalize the mimetype (strip 'application/' prefix, lowercase) if stored values don't match the 'pdf'/'docx' literals expected by the case statement.
- Handle the returned Result (success=false, empty text) gracefully rather than assuming extracted text exists.
- Extend the case statement to support additional types if those uploads must be indexed, or configure a remote extractor for them.
Example fix
// before
case mimetype
when "pdf" then extract_pdf
when "docx" then extract_docx
else
Rails.logger.warn("[LocalTextExtractor] Unsupported MIME type: #{attachment.mimetype}")
Result.new("", false)
end
// after: normalize mimetype and pre-validate
type = attachment.mimetype.to_s.split("/").last.downcase
case type
when "pdf" then extract_pdf
when "vnd.openxmlformats-officedocument.wordprocessingml.document", "docx" then extract_docx
else
Rails.logger.warn("[LocalTextExtractor] Unsupported MIME type: #{attachment.mimetype}")
Result.new("", false)
end Defensive patterns
Strategy: fallback
Validate before calling
// before invoking extraction
SUPPORTED = %w[pdf docx].freeze
type = attachment.mimetype.to_s.split('/').last.downcase
unless SUPPORTED.include?(type)
Rails.logger.info("Skipping local extraction for attachment #{attachment.id}: #{attachment.mimetype}")
return
end Type guard
def extractable?(attachment)
%w[pdf docx].include?(attachment.mimetype.to_s.split('/').last.downcase)
end Try / catch
result = FileTextExtractionService.new(attachment: attachment).call
if result.success
use(result.text)
else
Rails.logger.info("No text extracted for attachment #{attachment.id}; falling back to remote extractor")
end Prevention
- Whitelist allowed upload mimetypes at ingest time so extractors only see supported types.
- Check the Result flag (success) instead of assuming text is non-empty.
- Normalize mimetypes (lowercase, strip 'application/') before comparison.
- Route unsupported types to a remote extraction service instead of the local extractor.
When it happens
Trigger: Calling the service's #call with an attachment whose mimetype is anything other than pdf or docx (e.g. txt, pptx, xlsx, images, odp), causing the case statement to fall into the else branch.
Common situations: Users upload unsupported file types (plain text, spreadsheets, images) to a context that expects extracted text; mimetypes stored inconsistently (e.g. 'application/pdf' vs 'pdf') causing the case match to miss; feature routes all attachments through the local extractor instead of a remote extraction service.
Related errors
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/c3871d4b681e2142.
Report an issue: GitHub.
Appendix: source
Thrown at app/services/file_text_extraction_service.rb:46
Result = Struct.new(:text, :contains_images)
def initialize(attachment:)
@attachment = attachment
end
def call
memory_limit = Setting.get("attachment_calculate_words_memory_limit", 4.gigabytes.to_s).to_i
time_limit = Setting.get("attachment_calculate_words_time_limit", 3.minutes.to_s).to_f
MemoryLimit.apply(memory_limit) do
Timeout.timeout(time_limit) do
case mimetype
when "pdf"
extract_pdf
when "docx"
extract_docx
else
Rails.logger.warn("[LocalTextExtractor] Unsupported MIME type: #{attachment.mimetype}")
Result.new("", false)
end
end
end
rescue => e
Rails.logger.error("[LocalTextExtractor] Failed for attachment #{attachment.id}: #{e.message}")
Result.new("", false)
end
private
attr_reader :attachment
def mimetype
return "pdf" if attachment.mimetype == "application/pdf"
"docx" if %w[
application/vnd.openxmlformats-officedocument.wordprocessingml.documentView on GitHub (pinned to 1c9f0bb801)