Content-Disposition

File downloads and inline rendering are controlled by the Content-Disposition response header, which indicates whether the browser displays content directly or triggers a download dialog.

Usage

In a standard HTTP response, the Content-Disposition header controls how the browser presents content to the user. Setting the value to inline tells the browser to render the content directly. Setting the value to attachment triggers a download dialog instead.

This header also plays a role in multipart/form-data responses and form submissions. Each part of a multipart body includes its own Content-Disposition field, identifying the form field name and optional filename for uploaded files. The part boundary is defined in the Content-Type header.

Directives

inline

The inline directive instructs the browser to display the content directly within the page. This is the default behavior for most responses when Content-Disposition is absent.

attachment

The attachment directive triggers a download prompt. The browser presents a "Save As" dialog rather than rendering the content in the viewport.

filename

The filename parameter suggests a default filename for the downloaded file. The value is enclosed in double quotes and follows ASCII encoding rules.

Content-Disposition: attachment; filename="report.pdf"

filename*

The filename* parameter extends filename with support for character encoding beyond ASCII. When both filename and filename* are present, filename* takes priority. This is useful for filenames containing non-ASCII characters.

Content-Disposition: attachment; filename="document.pdf"; filename*=UTF-8''d%C3%B6cument.pdf

form-data

The form-data directive appears in multipart body parts and identifies the content as belonging to a form submission.

name

The name parameter is required within multipart body parts and identifies the form field the part corresponds to.

Example

A server responding with a CSV file download sets attachment and provides a suggested filename. The browser opens a save dialog with "export.csv" pre-filled.

Content-Disposition: attachment; filename="export.csv"

A server displaying a PDF directly in the browser uses inline. The browser renders the PDF in its built-in viewer rather than downloading the file.

Content-Disposition: inline

In a multipart form submission, each part carries its own Content-Disposition field. The name parameter maps the part to the corresponding form field, and filename indicates the original name of an uploaded file.

Content-Disposition: form-data; name="avatar"; filename="photo.jpg"

Troubleshooting

Download and display problems with Content-Disposition typically stem from incorrect directive values or filename encoding mistakes.

  1. File downloads with the wrong filename. The browser uses the filename parameter as the default save name. A missing or malformed filename value causes the browser to fall back to the URL path or a generic name. Ensure the value is enclosed in double quotes: filename="report.pdf". Verify the header with curl -I https://example.re/file and check the filename parameter in the response.

  2. Non-ASCII characters in filenames break or display as garbage. The filename parameter supports only ASCII characters. For names with accented letters, CJK characters, or other non-ASCII text, add the filename* parameter using the encoding syntax: filename*=UTF-8''d%C3%B6cument.pdf. Include both filename (ASCII fallback) and filename* (encoded version) for maximum compatibility across browsers.

  3. Browser ignores attachment and displays content inline. Some browsers override attachment for content types they render natively, such as PDFs and images. The Content-Type header influences this behavior. Setting Content-Type: application/octet-stream alongside attachment forces a download for any file type. Browser extensions and built-in viewers (PDF.js) can also override the directive.

  4. Inline display triggered when download is expected. A missing Content-Disposition header defaults to inline for most content types. The server must explicitly send attachment to trigger a download. In nginx, add add_header Content-Disposition "attachment"; to the relevant location block. In Apache, use Header set Content-Disposition "attachment" within a <Location> or <FilesMatch> directive.

  5. filename vs filename precedence.* When both parameters are present, filename* takes priority in all modern browsers. Older clients that do not support filename* fall back to filename. Always include both parameters. The filename* value must use percent-encoding for special characters: filename*=UTF-8''na%C3%AFve.txt.

  6. Framework-specific download response helpers. Most web frameworks provide built-in methods for setting download headers. Django uses FileResponse with the as_attachment parameter. Express uses res.download(). Flask uses send_file() with as_attachment=True. Rails uses send_data or send_file with a disposition option. These methods handle filename encoding and header formatting, reducing the chance of manual errors.

See also

Last updated: April 4, 2026