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

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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

@Kludex Kludex left a comment

Copy link
Copy Markdown
Owner

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

3 participants