Mixed Content Errors in Odoo with HTTPS
When Odoo runs behind an SSL-terminating reverse proxy (Nginx, Apache, Cloudflare), browsers may block resources with:
Mixed Content: The page at 'https://odoo.example.com/web' was loaded over HTTPS,
but requested an insecure resource 'http://odoo.example.com/web/assets/...'.
This request has been blocked; the content must be served over HTTPS.
Blocker: Mixed Active Content blocked
URL: http://odoo.example.com/web/content/123-image.pngThe page loads but appears broken — missing CSS, JavaScript, or images — because the browser blocks HTTP resources on an HTTPS page.
Why This Happens
Odoo generates URLs based on what it sees in incoming requests. When a reverse proxy terminates SSL and forwards plain HTTP to Odoo:
Browser ---HTTPS---> Nginx ---HTTP---> Odoo (port 8069)
# Odoo sees HTTP, so it generates HTTP URLs:
http://odoo.example.com/web/assets/bundle.js ← BLOCKED by browserOdoo needs to know the original request was HTTPS so it generates HTTPS URLs.
Fix 1: Enable proxy_mode in Odoo
This is the primary fix. Tell Odoo it runs behind a proxy:
# In odoo.conf
[options]
proxy_mode = TrueThen restart Odoo. With proxy_mode = True, Odoo reads the X-Forwarded-Proto header to determine the original protocol.
Fix 2: Configure Reverse Proxy Headers
The reverse proxy must forward the original protocol information:
# Nginx configuration
server {
listen 443 ssl;
server_name odoo.example.com;
location / {
proxy_pass http://127.0.0.1:8069;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme; # Critical!
proxy_set_header X-Forwarded-Host $host;
proxy_redirect off;
}
}The X-Forwarded-Proto $scheme line is essential. Without it, Odoo does not know the original request was HTTPS even with proxy_mode enabled.
Fix 3: Apache Configuration
# Apache reverse proxy
ServerName odoo.example.com
SSLEngine on
ProxyPass / http://127.0.0.1:8069/
ProxyPassReverse / http://127.0.0.1:8069/
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Forwarded-Host "odoo.example.com"
ProxyPreserveHost On
Fix 4: Redirect Loop Issues
Sometimes enabling proxy_mode causes infinite redirects. This happens when both Odoo and the proxy try to redirect HTTP to HTTPS:
# In Nginx, redirect HTTP to HTTPS only at the proxy level
server {
listen 80;
server_name odoo.example.com;
return 301 https://$server_name$request_uri;
}
# Do NOT add redirect rules in Odoo config
# proxy_mode = True is sufficientFix 5: Cloudflare-Specific Configuration
When using Cloudflare as a proxy:
# Cloudflare terminates SSL and may forward HTTP to Nginx
# Set Cloudflare SSL mode to "Full" or "Full (Strict)"
# NOT "Flexible" — Flexible causes mixed content because:
# Browser --HTTPS--> Cloudflare --HTTP--> Nginx --HTTP--> Odoo
# With Full SSL:
# Browser --HTTPS--> Cloudflare --HTTPS--> Nginx --HTTP--> Odoo
# And X-Forwarded-Proto: https is correctly setFix 6: Force HTTPS URLs in Database
If Odoo has already generated HTTP URLs stored in the database (e.g., in email templates):
# Update base URL
# Settings > Technical > System Parameters
# Key: web.base.url
# Value: https://odoo.example.com (with https://)
# Via SQL:
sudo -u postgres psql -d mydb -c "
UPDATE ir_config_parameter
SET value = 'https://odoo.example.com'
WHERE key = 'web.base.url';
"Fix 7: Websocket / Longpolling Mixed Content
The longpolling endpoint also needs HTTPS:
# Nginx — websocket proxy
location /websocket {
proxy_pass http://127.0.0.1:8072;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
}Verification
# Check if proxy headers are reaching Odoo
curl -v -H "X-Forwarded-Proto: https" http://127.0.0.1:8069/web
# Check web.base.url
sudo -u postgres psql -d mydb -c "SELECT value FROM ir_config_parameter WHERE key='web.base.url';"Prevention
DeployMonkey configures SSL termination, proxy_mode, and all forwarding headers automatically during instance provisioning. The AI agent validates HTTPS configuration end-to-end, preventing mixed content issues entirely.