How to configure browser preview behavior for OSS objects?

Updated at:

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.

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: true and Content-Disposition: attachment headers 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:

    1. 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.

    2. 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.

    3. Access the object with the new domain: Access the object through your custom domain URL. The object now previews inline.

Note
  • 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-Disposition metadata is set to attachment, 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-Disposition metadata to inline

    • Modify via the console

      1. Log on to the OSS console and navigate to the Objects page in the Object Management section of the target bucket.

      2. Find the target object. Click the icon in the Actions column and select Set Object Metadata.

      3. In the dialog box that appears, find the Content-Disposition field and change its value to inline.

      4. 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 with Content-Type set to application/octet-stream downloads because the browser cannot identify the file type.

  • Solution: Set the correct Content-Type for the object

    • Modify via the console

      1. Log on to the OSS console and navigate to the Objects page in the Object Management section of the target bucket.

      2. Find the target object. Click the icon in the Actions column and select Set Object Metadata.

      3. In the dialog box that appears, find the Content-Type field and change it to the correct value.

      4. Click OK to save the settings.

      Examples of correct Content-Type for common file types:

      • Images: image/jpeg, image/png, image/gif, image/webp

      • Videos: video/mp4

      • PDF documents: application/pdf

      • HTML files: text/html

      • Plain 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 update
    • Modify by using the CopyObject SDK

      When you use CopyObject to copy an object, the COPY metadata 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 the Content-Type based on the file name extension of the destination object. In this case, if you only specify Content-Type in the request without setting x-oss-metadata-directive to REPLACE, the setting does not take effect, and the destination object retains the Content-Type of the source object.

      Valid values of x-oss-metadata-directive:

      • COPY (default): copies the metadata of the source object and ignores metadata such as Content-Type specified 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 both Content-Type and x-oss-metadata-directive: REPLACE to update the Content-Type of 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_meta method to directly update the Content-Type of an existing object, or specify Content-Type when you upload an object by using put_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:SecureTransport condition, 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:

    1. Log on to the OSS console . Click the target bucket. In the navigation pane on the left, click Access Control > Bucket Policy

    2. Check whether the policy list contains a policy whose Condition limits the access method to HTTP and whose Effect is Deny.

    3. 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:// with https:// 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 Access Control > Bucket Policy, remove or modify the policy that contains the acs:SecureTransport condition. 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-Disposition metadata to attachment as described in Scenario 2. Best for permanent, per-file settings.

  • Method 2: Configure in CDN. Add Content-Disposition: attachment as 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

0048-00000001

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

0048-00000001

14:00, November 25, 2019

China (Hong Kong)

Buckets created after the policy takes effect

text/html

0048-00000001

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

0048-00000100

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

0048-00000101

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

0048-00000102

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

0048-00000103

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

0048-00000104

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

0048-00000105

00:00, October 09, 2022

All regions

Buckets created by users who activated OSS for the first time after 00:00 on October 9, 2022

All

0048-00000113

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

0048-00000114

Acceleration endpoints

Effective time

Region

Affected resources

Affected file types

Error code

00:00, December 31, 2020

All regions

Buckets for which transfer acceleration is enabled after the policy takes effect

text/html

0048-00000002

12:00, January 07, 2021

UAE (Dubai)

Buckets for which transfer acceleration is enabled after the policy takes effect

All

0048-00000107

18:00, January 07, 2021

Malaysia (Kuala Lumpur), UK (London)

Buckets for which transfer acceleration is enabled after the policy takes effect

All

0048-00000108

18:00, January 08, 2021

Japan (Tokyo), Indonesia (Jakarta), Germany (Frankfurt)

Buckets for which transfer acceleration is enabled after the policy takes effect

All

0048-00000109

12:00, January 14, 2021

US (Silicon Valley), US (Virginia), Singapore

Buckets for which transfer acceleration is enabled after the policy takes effect

All

0048-00000110

00:00, January 16, 2021

China (Hong Kong)

Buckets for which transfer acceleration is enabled after the policy takes effect

All

0048-00000111

00:00, October 09, 2022

All regions

Buckets created by users who activated OSS for the first time after 00:00 on October 9, 2022

All

0048-00000113

00:00, February 01, 2023

South Korea (Seoul), Philippines (Manila), Thailand (Bangkok)

Buckets for which transfer acceleration is enabled after the policy takes effect

All

0048-00000112