Have you ever clicked a file on a website expecting it to download, only to see a browser page filled with strange characters such as:
����P�F��x��...
Or perhaps a PDF downloaded instead of opening in the browser, a CSS file was interpreted incorrectly, or a file with an unusual extension appeared as plain text.
In many cases, the file itself is perfectly fine.
The real problem is that the web server told the browser the wrong thing about the file.
This is where concepts such as MIME types, HTTP headers, Apache, Nginx, and .htaccess become important.
This guide explains these concepts from the ground up, without assuming previous server administration experience.
1. What Happens When You Download a File From a Website?
When you enter an address such as:
https://example.com/files/manual.pdf
your browser sends a request to the web server.
The server then sends a response containing two main things:
- HTTP headers
- The actual file data
A simplified response might look like this:
HTTP/1.1 200 OK
Content-Type: application/pdf
Content-Length: 245812
After the headers comes the actual PDF file.
The important line here is:
Content-Type: application/pdf
This tells the browser:
“The data I am sending you is a PDF document.”
The browser can then decide whether to display it, download it, or pass it to another application.
2. What Is a MIME Type?
A MIME type is a standardized way of describing what kind of content a file contains.
MIME originally stood for:
Multipurpose Internet Mail Extensions
Although MIME started with email, the same system became extremely important on the web.
A MIME type normally consists of two parts:
type/subtype
For example:
text/html
image/jpeg
application/pdf
The first part describes the general category.
The second part describes the specific format.
3. Common MIME Types
Here are some MIME types you will encounter frequently.
| File | MIME type |
|---|---|
| HTML | text/html |
| CSS | text/css |
| JavaScript | text/javascript |
| Plain text | text/plain |
| JPEG | image/jpeg |
| PNG | image/png |
| GIF | image/gif |
| SVG | image/svg+xml |
application/pdf | |
| ZIP | application/zip |
| JSON | application/json |
| XML | application/xml |
| MP4 | video/mp4 |
| MP3 | audio/mpeg |
There is also a very useful generic type:
application/octet-stream
This essentially means:
“This is arbitrary binary data.”
Browsers commonly treat application/octet-stream as something that should be downloaded instead of displayed.
4. File Extension vs MIME Type
A common misconception is that browsers determine a file’s type entirely from its extension.
For example:
document.pdf
archive.zip
photo.jpg
The extension is important, but when files are delivered over HTTP, the server normally sends a Content-Type header.
For example:
Content-Type: application/zip
The browser uses this information when deciding what to do with the response.
This means a server could theoretically send:
picture.jpg
with:
Content-Type: text/plain
The browser might then try to handle the JPEG as text.
That can result in a screen filled with strange characters.
5. Why Binary Files Look Like Garbage When Displayed as Text
Files such as:
- ZIP archives
- executables
- images
- videos
- compressed backups
contain binary data.
Binary files are not meant to be displayed as normal characters.
If a browser receives a binary file but decides to display it as text, you may see something like:
�PNG
IHDR����
��x��...
or:
PK���...
The important thing to understand is:
This does not necessarily mean that the file is damaged.
The browser may simply be interpreting binary bytes as text characters.
6. The HTTP Content-Type Header
The HTTP header responsible for describing the file format is:
Content-Type
Examples:
Content-Type: text/html
Content-Type: application/pdf
Content-Type: application/zip
Content-Type: image/jpeg
For unknown binary files, a server administrator may use:
Content-Type: application/octet-stream
This is often appropriate for files that should simply be downloaded.
7. Content-Disposition: Open or Download?
There is another very important HTTP header:
Content-Disposition
This header can tell the browser whether the content should normally be displayed or downloaded.
For example:
Content-Disposition: inline
means:
Display the file inside the browser if possible.
While:
Content-Disposition: attachment
means:
Treat the response as a downloadable file.
A server can also suggest a filename:
Content-Disposition: attachment; filename="archive.zip"
The browser will normally show a download dialog using that filename.
8. Content-Type and Content-Disposition Work Together
These two headers solve slightly different problems.
Content-Type tells the browser:
What is this file?
Content-Disposition tells the browser:
What should I normally do with it?
For example:
Content-Type: application/pdf
Content-Disposition: inline
usually causes the PDF to open in the browser.
But:
Content-Type: application/pdf
Content-Disposition: attachment
normally causes the PDF to download.
For an unusual binary file:
Content-Type: application/octet-stream
Content-Disposition: attachment
is a common and safe combination.
9. Why Unusual File Extensions Can Cause Problems
Web servers usually maintain a list mapping file extensions to MIME types.
For example:
.html → text/html
.jpg → image/jpeg
.pdf → application/pdf
.zip → application/zip
But imagine you have files such as:
backup.zip.001
backup.zip.002
backup.zip.003
These may be parts of a split archive.
The web server may look only at the final extension:
.001
.002
.003
These extensions may not exist in the server’s MIME type database.
The server may therefore:
- use a default MIME type;
- return
text/plain; - return
application/octet-stream; - omit an expected type;
- allow another server component to guess.
The result depends on the hosting configuration.
10. What Is Apache?
Apache HTTP Server is one of the most widely used web servers.
Its job is to receive HTTP requests and return web pages, images, scripts, downloads, API responses, and other content.
A typical WordPress website may run something like:
Browser
↓
Apache
↓
PHP
↓
WordPress
↓
MySQL/MariaDB
Apache can be configured globally by the server administrator.
It can also, depending on the hosting setup, allow directory-level configuration through a special file called:
.htaccess
11. What Is .htaccess?
.htaccess is a configuration file used by Apache and compatible servers.
The name literally begins with a dot:
.htaccess
It normally contains Apache directives that apply to a directory and its subdirectories.
For example, .htaccess can be used for:
- redirects;
- URL rewriting;
- WordPress permalinks;
- access restrictions;
- MIME types;
- security headers;
- caching rules;
- compression;
- forcing downloads.
12. A Simple .htaccess Example
Suppose you want files ending in .bin to be treated as binary downloads.
You might use:
AddType application/octet-stream .bin
Or for more control:
<FilesMatch "\.bin$">
ForceType application/octet-stream
</FilesMatch>
This tells Apache that matching files should be returned as:
Content-Type: application/octet-stream
13. Forcing a File to Download With Apache
If Apache’s mod_headers module is available, you can also add:
<FilesMatch "\.bin$">
ForceType application/octet-stream
Header set Content-Disposition "attachment"
</FilesMatch>
The server will then return something similar to:
Content-Type: application/octet-stream
Content-Disposition: attachment
That strongly encourages the browser to download the file.
14. Matching Split Archive Files
Suppose your site contains:
archive.zip.001
archive.zip.002
archive.zip.003
A regular expression can match all three-digit archive parts:
<FilesMatch "\.zip\.[0-9]{3}$">
ForceType application/octet-stream
Header set Content-Disposition "attachment"
</FilesMatch>
This matches:
archive.zip.001
archive.zip.021
archive.zip.999
but not:
archive.zip
archive.zip.old
archive.zip.01
15. AddType vs ForceType
Apache offers several ways to control MIME types.
AddType
Example:
AddType application/octet-stream .001 .002 .003
This associates particular extensions with a MIME type.
It works well when you know the extensions in advance.
However, hundreds of numbered extensions would obviously be inconvenient.
ForceType
Example:
<FilesMatch "\.zip\.[0-9]{3}$">
ForceType application/octet-stream
</FilesMatch>
This is more flexible because you can use a regular expression to select files.
For numbered archive parts, FilesMatch plus ForceType is often more practical.
16. Where Should .htaccess Be Placed?
A .htaccess file applies to the directory in which it is located and usually its children.
For example:
public_html/
├── .htaccess
├── index.php
└── downloads/
├── file.zip
└── archive.zip.001
Rules in:
public_html/.htaccess
may affect the entire website.
But you can create another file:
public_html/downloads/.htaccess
containing rules specifically for downloads.
This is often preferable because it limits the configuration to the directory that actually needs it.
17. Why Limiting .htaccess Rules Is a Good Idea
Imagine adding:
ForceType application/octet-stream
to the root of a website without restricting it.
Suddenly Apache might start treating:
- HTML pages;
- CSS;
- JavaScript;
- images;
as generic downloads.
The website could stop displaying correctly.
For that reason, rules should normally be as specific as possible.
For example:
<FilesMatch "\.zip\.[0-9]{3}$">
ForceType application/octet-stream
</FilesMatch>
is much safer.
18. What Is Nginx?
Nginx, pronounced roughly as “engine-x”, is another extremely popular web server.
It is known for:
- high performance;
- efficient static file delivery;
- reverse proxying;
- load balancing;
- handling large numbers of concurrent connections.
Many websites use Nginx instead of Apache.
Others use both.
19. Nginx Does Not Use .htaccess
This is one of the most important differences beginners need to know.
Nginx does not read .htaccess files.
If your website runs purely on Nginx, adding:
.htaccess
will normally do absolutely nothing.
Nginx configuration is usually stored in server configuration files such as:
/etc/nginx/nginx.conf
or:
/etc/nginx/sites-enabled/example.conf
The exact location depends on the operating system and hosting setup.
20. The Nginx Equivalent
A simplified Nginx rule might look like:
location ~* \.zip\.[0-9]{3}$ {
default_type application/octet-stream;
add_header Content-Disposition "attachment";
}
This tells Nginx to treat matching files as downloadable binary content.
After changing Nginx configuration, an administrator would normally validate it:
nginx -t
and then reload Nginx:
systemctl reload nginx
On managed hosting, however, users may not have access to these commands.
21. Apache and Nginx Can Be Used Together
Many hosting environments use both servers.
A common configuration looks like:
Internet
↓
Nginx
↓
Apache
↓
PHP / WordPress
Nginx may act as:
- a reverse proxy;
- an SSL terminator;
- a static file server;
- a caching layer.
Apache may then process WordPress and PHP.
This can make troubleshooting slightly confusing.
You may add the correct rule to .htaccess, but if Nginx serves the file directly before Apache sees the request, the .htaccess rule may never be used.
22. How Can You Tell Which Web Server You Are Using?
One easy test is to inspect the HTTP response headers.
From Linux, macOS, or Windows with curl, run:
curl -I https://example.com/file.zip
You might see:
HTTP/2 200
server: nginx
content-type: application/zip
content-length: 1234567
Or:
Server: Apache
However, this is not definitive.
A reverse proxy, CDN, or hosting platform may hide the actual backend server.
23. Useful curl Commands for Troubleshooting
curl is extremely useful for checking download problems.
Show headers only
curl -I https://example.com/download/file.bin
Look for:
Content-Type
Content-Disposition
Content-Length
Server
Show headers and follow redirects
curl -IL https://example.com/download/file.bin
The -L option follows redirects.
This is useful because a file may first redirect through:
- HTTPS enforcement;
- a CDN;
- authentication;
- WordPress;
- another domain.
Download the file
curl -O https://example.com/download/file.bin
-O saves the file using the remote filename.
24. Checking Headers in Your Browser
Modern browsers also allow you to inspect headers.
In Chrome, Edge, Firefox, and similar browsers:
- Open Developer Tools.
- Open the Network tab.
- Load the file.
- Select the request.
- View Response Headers.
You may see:
content-type: application/octet-stream
content-disposition: attachment
content-length: 4739201
This is often the fastest way to understand why the browser behaves a certain way.
25. MIME Type Problems and WordPress
WordPress introduces another layer.
There are two different situations.
File served directly by the web server
Example:
https://example.com/wp-content/uploads/file.zip
In many configurations, Nginx or Apache serves this file directly.
WordPress PHP code may not be involved at all.
File served through PHP
A plugin or custom script may instead generate the download.
For example:
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="download.bin"');
readfile($file);
In this case, PHP controls the HTTP headers.
Editing .htaccess may therefore not solve the problem.
26. PHP Can Also Force Downloads
A simple PHP download script might look like:
<?php
$file = '/path/to/archive.bin';
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . basename($file) . '"');
header('Content-Length: ' . filesize($file));
readfile($file);
exit;
This gives PHP full control over how the browser receives the file.
However, for very large files, directly serving the file through Nginx or Apache is usually more efficient.
27. Why You Should Not Use PHP for Every Large Download
PHP is excellent for dynamic applications.
It is not always the best tool for transferring multi-gigabyte files.
If PHP reads and sends the entire file, the download may consume:
- PHP workers;
- memory;
- execution time;
- server resources.
Static web servers such as Nginx and Apache are generally better at delivering large files directly.
For protected downloads, techniques such as:
X-Sendfile
or:
X-Accel-Redirect
can allow PHP to authorize the request while the web server performs the actual file transfer.
28. What Is application/octet-stream?
This MIME type deserves special attention.
application/octet-stream
means generic binary data.
It does not tell the browser exactly what application should open the file.
Instead, it essentially says:
“Treat this as raw binary data.”
It is commonly used for:
- unknown file types;
- proprietary formats;
- archive fragments;
- binary backups;
- firmware files;
- files intended purely for download.
29. Does application/octet-stream Guarantee a Download?
Not absolutely.
Browsers ultimately control their own behavior.
However, combining:
Content-Type: application/octet-stream
with:
Content-Disposition: attachment
is a strong and standard way to request download behavior.
30. What Is MIME Sniffing?
Browsers sometimes try to determine the real file format by looking at the contents.
This behavior is known as:
MIME sniffing
For example, a server may say:
Content-Type: text/plain
but the browser might inspect the first bytes and realize that the response looks like HTML.
This historically helped websites with badly configured servers.
Unfortunately, MIME sniffing can also create security problems.
31. The X-Content-Type-Options Security Header
Websites can tell browsers not to guess MIME types by sending:
X-Content-Type-Options: nosniff
This is generally considered a useful security header.
For example:
X-Content-Type-Options: nosniff
tells the browser:
Respect the declared MIME type rather than trying to reinterpret the file.
This makes correct server configuration even more important.
If the server declares the wrong MIME type, the browser is less likely to compensate for the mistake.
32. MIME Types and Website Security
Incorrect MIME types are not only inconvenient.
They can sometimes create security risks.
Imagine a file uploaded by a user that contains HTML or JavaScript.
If the server returns it with an executable web MIME type, the browser might interpret the content rather than simply downloading it.
Secure upload systems should therefore consider:
- allowed extensions;
- actual file content;
- MIME types;
- storage location;
- response headers;
- permissions.
Never assume that checking only the filename is sufficient security.
33. MIME Types for CSS and JavaScript Matter Too
Incorrect MIME types can break websites.
Imagine a stylesheet served as:
Content-Type: text/plain
instead of:
Content-Type: text/css
Some browsers may refuse to apply it.
Likewise JavaScript should have an appropriate MIME type.
A browser console might report an error similar to:
Refused to execute script because its MIME type is not executable.
This is particularly common when:
X-Content-Type-Options: nosniff
is enabled.
34. How Apache Knows MIME Types
Apache commonly uses the mod_mime module.
Its configuration maps extensions to MIME types.
A system MIME database may contain entries similar to:
text/html html htm
image/jpeg jpeg jpg
application/pdf pdf
application/zip zip
Apache looks at the filename extension and applies the configured type.
You can supplement these mappings using .htaccess if your hosting provider permits it.
35. How Nginx Knows MIME Types
Nginx commonly loads MIME mappings from a file called:
mime.types
A configuration may include:
http {
include mime.types;
}
Inside mime.types, entries may resemble:
types {
text/html html htm;
text/css css;
image/jpeg jpeg jpg;
application/pdf pdf;
application/zip zip;
}
For unknown extensions, Nginx uses its configured default type.
A common default is:
default_type application/octet-stream;
36. What About Files With Multiple Extensions?
Consider:
database.backup.gz
or:
archive.tar.gz
or:
largefile.zip.001
Which extension matters?
That depends on the server and its configuration.
A server may recognize:
.gz
but not:
.001
For:
largefile.zip.001
the final extension is normally:
.001
Therefore, the server may not automatically recognize it as part of a ZIP archive.
This is why custom MIME rules can be useful.
37. Split ZIP Archives Explained
Large archives are sometimes divided into smaller parts:
backup.zip.001
backup.zip.002
backup.zip.003
Each individual file is only part of the full archive.
Downloading one part alone normally does not produce a complete ZIP file.
All pieces must usually be downloaded into the same directory.
Extraction is then started from the first part:
backup.zip.001
Software such as 7-Zip can normally reconstruct the archive using the remaining pieces automatically.
38. Do Not Rename Split Archive Parts Arbitrarily
Suppose you have:
archive.zip.001
archive.zip.002
archive.zip.003
Renaming:
archive.zip.003
to:
archive.zip
does not magically create a valid archive.
The file contains only a portion of the complete data.
The parts need to remain together and in the correct order.
39. Content-Length and Downloads
Another useful HTTP header is:
Content-Length
Example:
Content-Length: 84572913
This tells the browser how many bytes the server intends to send.
It helps browsers:
- display download progress;
- estimate completion percentage;
- detect incomplete transfers.
A missing Content-Length does not necessarily indicate a problem because HTTP can also use chunked transfer encoding.
40. Range Requests and Resumable Downloads
For large downloads, another useful feature is HTTP range support.
A server may return:
Accept-Ranges: bytes
This allows a client to request only part of a file.
For example:
Range: bytes=1000000-
Range requests allow:
- paused downloads;
- resumed downloads;
- download managers;
- media seeking.
Apache and Nginx normally support byte ranges for static files.
41. What Is a 206 Partial Content Response?
When a client requests only part of a file, the server may answer:
HTTP/1.1 206 Partial Content
and include:
Content-Range: bytes 1000000-1999999/8000000
This is normal.
It does not mean that the server failed.
It simply means the server returned the requested portion of the file.
42. Why Downloads Sometimes Become Corrupted
If a downloaded file genuinely is corrupted, several causes are possible.
Examples include:
- interrupted upload;
- incomplete FTP transfer;
- disk corruption;
- server-side modification;
- PHP output being inserted before binary data;
- antivirus or security proxy interference;
- incomplete multipart archive;
- incorrect transfer mode in very old FTP software.
MIME types themselves generally do not change the underlying bytes of a static file.
They mainly tell the browser how to interpret those bytes.
43. How to Verify That a File Was Downloaded Correctly
A strong method is to compare cryptographic hashes.
On Linux:
sha256sum archive.zip.001
On Windows PowerShell:
Get-FileHash archive.zip.001 -Algorithm SHA256
You might obtain:
A5199D6F...
Run the same calculation on the original file.
If both SHA-256 hashes are identical, the files are byte-for-byte identical.
44. Download Problems Caused by CDNs
Modern websites may use a CDN such as:
- Cloudflare;
- Fastly;
- Akamai;
- Bunny;
- Amazon CloudFront.
The request path may therefore look like:
Browser
↓
CDN
↓
Nginx
↓
Apache
↓
Application
The CDN may:
- cache headers;
- modify compression;
- serve cached copies;
- apply content rules.
After changing the origin server configuration, you may need to purge the CDN cache before seeing the new behavior.
45. Browser Cache Can Also Mislead You
Browsers may cache:
- response bodies;
- redirects;
- MIME types;
- headers.
After changing server configuration, test using:
- a private/incognito window;
- Developer Tools with cache disabled;
curl;- another browser.
This helps distinguish a server problem from a stale browser cache.
46. Apache .htaccess Errors and HTTP 500
Incorrect .htaccess syntax can cause:
500 Internal Server Error
For example, a directive may require an Apache module that is unavailable.
If:
Header set Content-Disposition "attachment"
causes an error, the mod_headers module may not be enabled or allowed.
You could temporarily test:
<FilesMatch "\.bin$">
ForceType application/octet-stream
</FilesMatch>
If the website works again, the Header directive may have been the issue.
47. .htaccess May Be Disabled
Apache administrators can control whether .htaccess files are allowed using AllowOverride.
For example:
AllowOverride None
means .htaccess rules are ignored.
Whereas configurations such as:
AllowOverride All
permit many .htaccess directives.
On shared hosting, this is controlled by the hosting provider.
48. Why Nginx Avoids .htaccess
Apache may search directories for .htaccess files while processing requests.
Nginx uses a different philosophy.
Its configuration is normally loaded centrally when the server starts or reloads.
This provides:
- predictable configuration;
- less per-request filesystem checking;
- centralized administration.
The disadvantage is that ordinary users cannot usually change Nginx settings simply by uploading an .htaccess file.
49. WordPress .htaccess Should Be Edited Carefully
A standard WordPress Apache configuration often includes rules similar to:
# BEGIN WordPress
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
# END WordPress
WordPress may regenerate portions between:
# BEGIN WordPress
and:
# END WordPress
For custom rules, it is usually safer to place them outside automatically managed sections unless you know exactly how your setup behaves.
50. A Dedicated Download Directory Is Often Better
Instead of scattering large files throughout a website, consider using:
/downloads/
For example:
public_html/
└── downloads/
├── .htaccess
├── package.zip.001
├── package.zip.002
└── package.zip.003
The directory can then have its own download configuration.
Example Apache configuration:
<FilesMatch "\.(zip|7z|rar|bin)$">
ForceType application/octet-stream
Header set Content-Disposition "attachment"
</FilesMatch>
<FilesMatch "\.zip\.[0-9]{3}$">
ForceType application/octet-stream
Header set Content-Disposition "attachment"
</FilesMatch>
This keeps download rules separate from the rest of the website.
51. Protecting a Download Directory
If files should not be publicly discoverable, remember that MIME configuration is not access control.
These lines:
ForceType application/octet-stream
Header set Content-Disposition "attachment"
do not protect the file.
Anyone who knows the URL may still download it.
Access protection requires something else, such as:
- authentication;
- signed URLs;
- application-level authorization;
- IP restrictions;
- expiring links;
- private object storage.
52. Do Not Confuse MIME Types With File Permissions
Linux file permissions such as:
644
755
600
control whether the operating system allows users or processes to access files.
MIME types control how HTTP clients interpret responses.
These are completely different concepts.
For example:
644
does not mean:
application/zip
and changing permissions will not normally fix an incorrect Content-Type.
53. MIME Type vs File Signature
A file extension says what someone claims the file is.
A MIME type says what the server claims the file is.
A file signature, sometimes called a magic number, gives clues about what the file actually contains.
For example, ZIP files commonly start with bytes corresponding to:
PK
PDF files normally begin with:
%PDF
PNG images begin with a defined binary signature.
Security software often checks these signatures rather than trusting filenames alone.
54. Why Upload Validation Should Not Trust MIME Types Alone
Suppose someone uploads:
photo.jpg
but the file actually contains executable or HTML content.
Checking only:
.jpg
is insufficient.
Likewise, browser-supplied MIME information can sometimes be forged.
Good upload validation may examine:
- extension;
- MIME type;
- file signature;
- file size;
- allowed format;
- storage location.
55. Compression Is Different From MIME Type
Another common source of confusion is:
Content-Encoding: gzip
This is not the same thing as:
Content-Type: application/gzip
Content-Type tells the browser what the resource is.
Content-Encoding tells the browser how the resource has been encoded for transport.
For example:
Content-Type: text/css
Content-Encoding: gzip
means:
This is a CSS file that has been compressed with gzip for transmission.
The browser decompresses it automatically.
56. Common HTTP Headers Worth Knowing
When diagnosing file downloads, these are especially useful:
Content-Type
Content-Disposition
Content-Length
Content-Encoding
Accept-Ranges
Content-Range
Cache-Control
ETag
Last-Modified
Server
Location
You do not need to memorize all of them.
For download problems, start with:
Content-Type
Content-Disposition
Those two explain a large percentage of browser behavior.
57. A Practical Troubleshooting Checklist
If clicking a file produces strange browser output instead of a download, work through these steps.
Step 1: Check the file on the server
Confirm that:
- the upload completed;
- the file size is correct;
- the filename is correct.
Step 2: Inspect the HTTP headers
Run:
curl -I https://example.com/path/file
Step 3: Check Content-Type
For an unknown binary file, something like this is usually appropriate:
application/octet-stream
Step 4: Check Content-Disposition
For a forced download:
attachment
Step 5: Determine the web server
Check whether the site uses:
- Apache;
- Nginx;
- both;
- a CDN.
Step 6: Apply the rule in the correct layer
Apache:
.htaccess
may work.
Nginx:
.htaccess
will not work.
Step 7: Clear caches
Check:
- browser cache;
- WordPress cache;
- reverse proxy cache;
- CDN cache.
Step 8: Test again
Use:
curl -I
instead of relying only on browser behavior.
58. Example: Correct Headers for an Ordinary ZIP File
A normal ZIP download might return:
HTTP/1.1 200 OK
Content-Type: application/zip
Content-Disposition: attachment; filename="package.zip"
Content-Length: 82938122
Accept-Ranges: bytes
This clearly tells the browser what the file is and that it should be downloaded.
59. Example: Correct Headers for an Unusual Binary Part
A split archive component might instead use:
HTTP/1.1 200 OK
Content-Type: application/octet-stream
Content-Disposition: attachment
Content-Length: 104857600
Accept-Ranges: bytes
This is perfectly reasonable because a file such as:
package.zip.017
does not need a specialized MIME type.
60. Common Beginner Mistakes
Several mistakes appear repeatedly when troubleshooting this problem.
Mistake 1: Assuming the file is corrupted because the browser displays garbage
Binary data displayed as text naturally looks like garbage.
Mistake 2: Renaming an archive fragment
A split archive part cannot normally become a complete archive by changing its filename.
Mistake 3: Adding .htaccess rules to an Nginx-only server
Nginx ignores .htaccess.
Mistake 4: Changing MIME types globally
A rule intended for downloads may accidentally affect the entire website.
Mistake 5: Forgetting CDN caching
The origin may be fixed while the CDN continues serving old headers.
Mistake 6: Confusing MIME type with security
application/octet-stream does not make a file private.
Mistake 7: Using PHP unnecessarily for large files
Static delivery through the web server is usually much more efficient.
61. Apache or Nginx: Which Is Better?
There is no universal winner.
Apache is popular because it is:
- mature;
- flexible;
- widely supported;
- compatible with
.htaccess; - convenient for shared hosting.
Nginx is popular because it is:
- efficient;
- fast at serving static files;
- excellent as a reverse proxy;
- suitable for high-concurrency workloads.
Many production platforms use both.
The important point is not which one is “better.”
The important point is knowing which server is responsible for the response you are troubleshooting.
62. The Most Important Concept to Remember
When you request a file from a website, the browser does not receive only the file.
It receives:
HTTP headers
+
file data
The headers describe how the data should be interpreted.
A perfectly valid binary file combined with incorrect headers can appear completely broken.
For example:
Correct binary file
+
Content-Type: text/plain
=
browser displays strange characters
while:
Correct binary file
+
Content-Type: application/octet-stream
+
Content-Disposition: attachment
=
browser downloads the file
The underlying file may be identical in both cases.
Conclusion
MIME types are one of those web technologies that remain invisible until something goes wrong.
When everything is configured properly, clicking a PDF opens a PDF, clicking an image shows an image, and clicking an archive downloads an archive.
Behind that apparently simple behavior are several important components:
- file extensions;
- MIME types;
- HTTP
Content-Type; Content-Disposition;- Apache;
- Nginx;
.htaccess;- PHP;
- reverse proxies;
- CDNs;
- browser behavior.
For beginners, the most useful diagnostic command to remember is:
curl -I https://example.com/file
Then look first at:
Content-Type
Content-Disposition
If a binary file is being displayed as unreadable characters, there is a good chance that nothing is wrong with the data itself.
The browser may simply have received the wrong instructions.
And once you know which server is sending those instructions, fixing the problem is usually much easier.
Frequently Asked Questions
What MIME type should I use for an unknown downloadable file?
A common choice is:
application/octet-stream
For download behavior, it can be combined with:
Content-Disposition: attachment
Can .htaccess configure Nginx?
No. Nginx does not process .htaccess files.
Does seeing strange characters mean my ZIP file is corrupt?
Not necessarily. A binary file displayed as text naturally looks like unreadable characters.
What header forces a browser to download a file?
Usually:
Content-Disposition: attachment
What header tells the browser what kind of file it received?
Content-Type
What does application/octet-stream mean?
It represents generic binary data and is commonly used for files intended for download.
Can WordPress control MIME types?
Yes, in some situations. However, static files in directories such as wp-content may be delivered directly by Apache, Nginx, or a CDN without WordPress PHP being involved.
Why did my .htaccess change have no effect?
Possible reasons include:
- the server uses Nginx;
- Apache has disabled
.htaccess; - Nginx serves the file before Apache;
- a CDN cached the old response;
- the matching rule is incorrect;
- another configuration overrides the header.
How do I check what MIME type a server is returning?
Use:
curl -I https://example.com/file
and inspect the Content-Type response header.
Is changing the MIME type enough to secure a download?
No. MIME types control how content is interpreted. Authentication and authorization are separate security mechanisms.


