Home About Blog

How can I fix Mixed Content errors when my site is accessed via HTTPS?

My site loads fine on HTTP but when I access the site via HTTPS instead some images are missing, styles are absent, and dynamic content doesn’t work.

Also my browser’s Developer Tools Console reports warnings and errors similar to this:

Mixed Content: The page at 'https://example.com/' was loaded over HTTPS, but requested an insecure image 'http://image.com/image.jpg'. This content should also be served over HTTPS.

How can I solve this?

You have several options.

Ideally you would fix the URLs embedded in the content served by your origin by replacing the http:// prefix with https:// on any absolute URLs. It is ok for HTTP pages to reference HTTPS resources, just not the other way, and HTTPS is fast and free on section.io. Preferring the HTTPS resource always can also have cache benefits in the browser and at section.io.

If you cannot change the content served by your origin, but you have a section.io proxy configured that can insert additional response headers, you can ask browsers to fix it themselves. For example, if you have Varnish Cache, you can use this custom VCL:

sub vcl_deliver {
    if (req.http.X-Forwarded-Proto == "https" && !resp.http.Content-Security-Policy) {
      set resp.http.Content-Security-Policy = "upgrade-insecure-requests";

This will add a Content-Security-Policy: upgrade-insecure-requests header which all modern browsers will honour and automatically translate any broken http:// URLs on your pages to https://.

Lastly, if you need to support older browsers or devices which don’t understand the Content-Security-Policy header and you have the OpenResty proxy in your section.io configuration, you can fix the URLs as the content passes through section.io with some Lua script similar to this:

if ngx.header["content-type"] ~= nil and string.find(ngx.header["content-type"], "^text/html") then
  local chunk, eof = gz.inflate_chunk()

  chunk = chunk:gsub("src=\"http://", "src=\"https://")