Skip to content

Use "application/octet-stream" as the FileResponse media type fallback#3283

Merged
Kludex merged 1 commit into
Kludex:mainfrom
ATOM00blue:fix-fileresponse-default-media-type
May 23, 2026
Merged

Use "application/octet-stream" as the FileResponse media type fallback#3283
Kludex merged 1 commit into
Kludex:mainfrom
ATOM00blue:fix-fileresponse-default-media-type

Conversation

@ATOM00blue
Copy link
Copy Markdown
Contributor

Summary

FileResponse falls back to text/plain when the media type cannot be guessed from the filename or path:

if media_type is None:
    media_type = guess_type(filename or path)[0] or "text/plain"

For files with an unrecognized extension this means the response is served as text/plain, so browsers render the bytes inline as text instead of downloading the file. This was reported in discussion #3106 (an Outlook .msg file rendered as text rather than triggering a download).

application/octet-stream is the correct default for unknown content per RFC 2046 ("MIME implementations must at a minimum treat any unrecognized subtypes as being equivalent to application/octet-stream") and the MDN guidance. It's also what Django and Werkzeug use:

The earlier choice of text/plain (#1027) was made on the assumption that Django used text/plain, which isn't the case.

This affects FileResponse directly and StaticFiles, which serves files through FileResponse. Passing an explicit media_type is unchanged.

Checklist

  • I understand that this PR may be closed in case there was no previous discussion. (This doesn't apply to typos!)
  • I've added a test for each change that was introduced, and I tried as much as possible to make a single atomic change.
  • I've updated the documentation accordingly.

When the media type cannot be guessed from the filename or path,
FileResponse fell back to text/plain. This causes browsers to render
unknown binary files (e.g. .msg) as text instead of downloading them.

application/octet-stream is the correct default for unrecognized types
per RFC 2046, and matches Django and Werkzeug.
Copilot AI review requested due to automatic review settings May 22, 2026 01:28
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates FileResponse to use a safer default Content-Type when a file’s MIME type cannot be inferred, aligning behavior with common HTTP/MIME expectations and improving browser handling of unknown file types.

Changes:

  • Change FileResponse fallback media type from text/plain to application/octet-stream when mimetypes.guess_type() cannot determine a type.
  • Add a regression test asserting the new fallback Content-Type behavior.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
starlette/responses.py Updates FileResponse default media type fallback to application/octet-stream.
tests/test_responses.py Adds a test covering the unknown-extension fallback Content-Type.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tests/test_responses.py
@Kludex Kludex changed the title Use application/octet-stream as the FileResponse media type fallback Use "application/octet-stream" as the FileResponse media type fallback May 23, 2026
Copy link
Copy Markdown
Owner

@Kludex Kludex left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense.

Thanks. 🙏

@Kludex Kludex merged commit 348f86d into Kludex:main May 23, 2026
11 of 12 checks passed
@Kludex Kludex mentioned this pull request May 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants