How to configure browser preview behavior for OSS objects?
When you access an OSS object through a browser, it may download instead of previewing inline. Use this guide to diagnose the cause and configure the correct preview behavior.
Troubleshooting
If an object downloads instead of previewing, run curl to inspect the response headers and identify the cause.
Goal: Check whether the response header contains fields that force a download.
Steps: Run the following command in your terminal. Replace <your-object-url> with your object URL.
curl -I "<your object URL>"Result analysis: Check the response for the x-oss-force-download and Content-Disposition fields.
If the response header contains
x-oss-force-download: true: A security policy for the OSS default domain name is triggered. For the solution, see Scenario 1: Forced download due to an OSS security policy.If the response header does not contain
x-oss-force-downloadbut containsContent-Disposition: attachment: The object's metadata is configured to download it as an attachment. For the solution, see Scenario 2: Forced download due to object metadata settings.If the response header contains neither of the preceding fields but the object is still downloaded: The browser likely cannot recognize the object's file type. For the solution, see Scenario 3: Browser fails to preview the object due to an incorrect Content-Type.
Solutions
Scenario 1: Forced download due to an OSS security policy
This scenario occurs when the response header contains x-oss-force-download: true.
Cause: OSS adds
x-oss-force-download: trueandContent-Disposition: attachmentheaders to prevent certain file types (such as HTML) from executing in browsers. This policy applies when you access objects through an OSS default domain name or an acceleration endpoint in buckets created after a specific date.For more information about the policies, see Appendix: Quick reference for OSS forced download rules at the end of this topic.
Solution: Use a custom domain name to access OSS resources
Procedure:
Map a custom domain: Log on to the OSS console. On the bucket's Domain Names page, map your custom domain name that has an ICP filing.
Configure a CNAME record: At your domain name provider, such as Alibaba Cloud DNS, add a CNAME record that points your custom domain name to the CNAME address provided by OSS.
Access the object with the new domain: Access the object through your custom domain URL. The object now previews inline.
For global acceleration, map your custom domain to an acceleration endpoint. This bypasses the forced download policy while providing accelerated access.
For detailed instructions, see Access OSS through a custom domain name.
Scenario 2: Forced download due to object metadata settings
This scenario occurs when the response header contains Content-Disposition: attachment but not x-oss-force-download.
Cause: The object's
Content-Dispositionmetadata is set toattachment, which forces the browser to download rather than display the object. If this setting is not cleared after temporary use, all subsequent requests trigger a download.Solution: Change the object's
Content-Dispositionmetadata toinlineModify via the console
Log on to the OSS console and navigate to the Objects page in the Object Management section of the target bucket.
Find the target object. Click the ┇ icon in the Actions column and select Set Object Metadata.
In the dialog box that appears, find the
Content-Dispositionfield and change its value toinline.Click OK to save the settings.
Modify in batches using ossutil
# Set the Content-Disposition of a specific object to inline. ossutil set-props oss://your-bucket/your-object.pdf --content-disposition inline --metadata-directive update
Scenario 3: Browser fails to preview the object due to an incorrect Content-Type
This scenario occurs when the response header is normal, but the browser still downloads the object.
Cause: The object's
Content-Type(MIME type) is missing or incorrect. For example, a JPG image withContent-Typeset toapplication/octet-streamdownloads because the browser cannot identify the file type.Solution: Set the correct
Content-Typefor the objectModify via the console
Log on to the OSS console and navigate to the Objects page in the Object Management section of the target bucket.
Find the target object. Click the ┇ icon in the Actions column and select Set Object Metadata.
In the dialog box that appears, find the
Content-Typefield and change it to the correct value.Click OK to save the settings.
Examples of correct Content-Type for common file types:
Images:
image/jpeg,image/png,image/gif,image/webpVideos:
video/mp4PDF documents:
application/pdfHTML files:
text/htmlPlain text:
text/plain
Modify in batches using ossutil
# Set the Content-Type of a specific object to image/jpeg. ossutil set-props oss://your-bucket/your-object.jpg --content-type image/jpeg --metadata-directive updateModify by using the
CopyObjectSDKWhen you use
CopyObjectto copy an object, theCOPYmetadata directive is used by default. This directive copies the metadata of the source object to the destination object as-is and does not automatically infer or update theContent-Typebased on the file name extension of the destination object. In this case, if you only specifyContent-Typein the request without settingx-oss-metadata-directivetoREPLACE, the setting does not take effect, and the destination object retains theContent-Typeof the source object.Valid values of
x-oss-metadata-directive:COPY(default): copies the metadata of the source object and ignores metadata such asContent-Typespecified in the request.REPLACE: replaces the metadata of the source object with the metadata specified in the request.
When you call
CopyObject, you must specify bothContent-Typeandx-oss-metadata-directive: REPLACEto update theContent-Typeof the destination object to the specified value. The following sample code uses the Python SDK:import oss2 # Initialize the bucket. auth = oss2.Auth('<your-access-key-id>', '<your-access-key-secret>') bucket = oss2.Bucket(auth, '<your-endpoint>', '<your-bucket-name>') # Set Content-Type and set the metadata directive to REPLACE when you copy an object. headers = { "Content-Type": "image/jpeg", "x-oss-metadata-directive": "REPLACE" } bucket.copy_object('<source-bucket-name>', 'source-object.png', 'target-object.jpg', headers=headers)Alternatively, you can use the
update_object_metamethod to directly update theContent-Typeof an existing object, or specifyContent-Typewhen you upload an object by usingput_object.
Scenario 4: Preview fails because a bucket policy enforces HTTPS
This scenario occurs when a request over HTTP returns the 403 AccessDenied error with the message Access denied by bucket policy. The object is neither previewed nor downloaded, and the same object is returned as expected when you request it over HTTPS.
Cause: The bucket policy of the bucket contains the
acs:SecureTransportcondition, which denies requests that are not sent over HTTPS. An HTTP request for the object URL is rejected by the bucket policy before the object is returned, so the browser has nothing to preview. Requests that use a custom domain name are subject to the same bucket policy as requests that use the OSS default domain name.Confirm the cause:
Log on to the OSS console . Click the target bucket. In the navigation pane on the left, click
Check whether the policy list contains a policy whose Condition limits the access method to HTTP and whose Effect is Deny.
Alternatively, query the bucket policy from the command line:
aliyun ossutil api get-bucket-policy --bucket <bucket-name>
Solution 1 (Recommended): Access the object over HTTPS. Replace
http://withhttps://in the object URL and request the object again. The object then previews in the browser, and the bucket continues to deny HTTP requests.Solution 2: Modify the bucket policy. If your business requires HTTP access, in the navigation pane on the left, click , remove or modify the policy that contains the
acs:SecureTransportcondition. Allowing HTTP requests means that data is transmitted in plain text, which reduces transmission security. Evaluate the impact before you change the policy.
Additional use cases and solutions
Changes to metadata do not take effect: Check the CDN cache
If you use CDN to accelerate access to OSS, metadata changes such as Content-Type or Content-Disposition may not take effect immediately because CDN nodes still serve the cached version.
Solution: Purge the CDN cache for the modified file's URL in the CDN console. Refresh and prefetch resources.
How to force an object to download instead of being previewed?
To always force a download when users access a file, use one of the following methods.
Method 1 (Recommended): Configure in OSS. Set the file's
Content-Dispositionmetadata toattachmentas described in Scenario 2. Best for permanent, per-file settings.Method 2: Configure in CDN. Add
Content-Disposition: attachmentas an outbound response header under Cache in the CDN console. This avoids modifying the source file and supports batch configuration by path or file type.
Browser does not support the file format for preview
Browsers cannot preview certain professional formats such as .psd, .ai, and .sketch. These files download regardless of OSS and CDN configuration.
Solution: Install a browser extension for the format, or use a document preview service such as WebOffice Online Preview.
Appendix: Quick reference for OSS forced download rules
Check the x-oss-ec value in the response header, then use the following tables to identify the matching rule.
Error code (x-oss-ec): Identifies the rule that triggered the download.
Bucket creation time: The policy typically applies only to buckets created after this time. Legacy buckets are usually not affected.
Transfer acceleration enabling time: The policy typically applies only to buckets with transfer acceleration enabled after this time. Buckets with transfer acceleration enabled earlier are usually not affected.
You can bypass all forced download rules using a custom domain name.
OSS default domain names
When the policy takes effect | Region | Affected resources | Affected file types | Error code |
08:00, September 28, 2018 | China (Hangzhou), China (Shanghai), China (Qingdao), China (Beijing), China (Zhangjiakou), China (Hohhot), China (Shenzhen), China (Chengdu) | Buckets created after the policy takes effect | text/html | |
12:00, September 25, 2019 | China (Nanjing - Local Region - Phasing Out), China (Fuzhou - Local Region - Phasing Out), China (Wuhan - Local Region), China (Ulanqab), China (Heyuan), China (Guangzhou), US (Silicon Valley), US (Virginia), South Korea (Seoul), Singapore, Malaysia (Kuala Lumpur), Indonesia (Jakarta), Philippines (Manila), Thailand (Bangkok), UK (London), UAE (Dubai) | Buckets created after the policy takes effect | text/html | |
14:00, November 25, 2019 | China (Hong Kong) | Buckets created after the policy takes effect | text/html | |
17:00, September 23, 2019 | China (Hohhot) | Buckets created after the policy takes effect | image/jpeg, image/gif, image/tiff, image/png, image/webp, image/svg+xml, image/bmp, image/x-ms-bmp, image/x-cmu-raster, image/exr, image/x-icon, image/heic, text/html | |
11:00, September 24, 2019 | China (Qingdao), China (Chengdu) | Buckets created after the policy takes effect | image/jpeg, image/gif, image/tiff, image/png, image/webp, image/svg+xml, image/bmp, image/x-ms-bmp, image/x-cmu-raster, image/exr, image/x-icon, image/heic, text/html | |
17:00, September 24, 2019 | China (Zhangjiakou) | Buckets created after the policy takes effect | image/jpeg, image/gif, image/tiff, image/png, image/webp, image/svg+xml, image/bmp, image/x-ms-bmp, image/x-cmu-raster, image/exr, image/x-icon, image/heic, text/html | |
17:00, September 29, 2019 | China (Shanghai), China (Shenzhen) | Buckets created after the policy takes effect | image/jpeg, image/gif, image/tiff, image/png, image/webp, image/svg+xml, image/bmp, image/x-ms-bmp, image/x-cmu-raster, image/exr, image/x-icon, image/heic, text/html | |
18:00, September 29, 2019 | China (Beijing) | Buckets created after the policy takes effect | image/jpeg, image/gif, image/tiff, image/png, image/webp, image/svg+xml, image/bmp, image/x-ms-bmp, image/x-cmu-raster, image/exr, image/x-icon, image/heic, text/html | |
15:00, September 30, 2019 | China (Hangzhou) | Buckets created after the policy takes effect | image/jpeg, image/gif, image/tiff, image/png, image/webp, image/svg+xml, image/bmp, image/x-ms-bmp, image/x-cmu-raster, image/exr, image/x-icon, image/heic, text/html | |
00:00, October 09, 2022 | Buckets created by users who activated OSS for the first time after 00:00 on October 9, 2022 | |||
10:00, December 22, 2025 | China (Fuzhou - Local Region - Phasing Out), China (Ulanqab), China (Heyuan), China (Guangzhou), China (Nanjing - Local Region - Phasing Out), China (Wuhan - Local Region) | Buckets created after the policy takes effect | image/jpeg, image/gif, image/tiff, image/png, image/webp, image/svg+xml, image/bmp, image/x-ms-bmp, image/x-cmu-raster, image/exr, image/x-icon, image/heic |
Acceleration endpoints
Effective time | Region | Affected resources | Affected file types | Error code |
00:00, December 31, 2020 | Buckets for which transfer acceleration is enabled after the policy takes effect | text/html | ||
12:00, January 07, 2021 | UAE (Dubai) | Buckets for which transfer acceleration is enabled after the policy takes effect | ||
18:00, January 07, 2021 | Malaysia (Kuala Lumpur), UK (London) | Buckets for which transfer acceleration is enabled after the policy takes effect | ||
18:00, January 08, 2021 | Japan (Tokyo), Indonesia (Jakarta), Germany (Frankfurt) | Buckets for which transfer acceleration is enabled after the policy takes effect | ||
12:00, January 14, 2021 | US (Silicon Valley), US (Virginia), Singapore | Buckets for which transfer acceleration is enabled after the policy takes effect | ||
00:00, January 16, 2021 | China (Hong Kong) | Buckets for which transfer acceleration is enabled after the policy takes effect | ||
00:00, October 09, 2022 | Buckets created by users who activated OSS for the first time after 00:00 on October 9, 2022 | |||
00:00, February 01, 2023 | South Korea (Seoul), Philippines (Manila), Thailand (Bangkok) | Buckets for which transfer acceleration is enabled after the policy takes effect |