Reverse proxying a VM of ERPNext with Cloudflare returns "Contradictory scheme headers"

Hello folks,

Grateful for any help here.

I’ve finally managed to get ERPNext running in an Ubuntu VM on my unRaid server and local network access seems to be working great with no problems.

I’ve tried to set up my SWAG container to use NGINX to forward erp.mydomain.com to the VM, which it does but generates the error:

Bad Request

Contradictory scheme headers

All of my domain DNS is done through Cloudflare and consequently forced to use SSL, so I am suspecting that NGINX on my server is sending an SSL request to the VM’s NGINX which is causing some confusion. It is my understanding that this contradictory scheme headers error comes from gunicorn, but I am patently unfamiliar with that software so far. I’ve poured over my nginx logs and found nothing of note there, but I can look elsewhere if need be.

My /etc/nginx/conf.d/frappe-bench.conf is as follows:

upstream frappe-bench-frappe {
	server 127.0.0.1:8000 fail_timeout=0;
}

upstream frappe-bench-socketio-server {
	server 127.0.0.1:9000 fail_timeout=0;
}



# setup maps


# server blocks





server {
	
	listen 80;
	listen [::]:80;

	server_name
		erpnext.local
		;

	root /home/frappe/frappe-bench/sites;

	

	proxy_buffer_size 128k;
	proxy_buffers 4 256k;
	proxy_busy_buffers_size 256k;

	

	add_header X-Frame-Options "SAMEORIGIN";
	add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
	add_header X-Content-Type-Options nosniff;
	add_header X-XSS-Protection "1; mode=block";
	add_header Referrer-Policy "same-origin, strict-origin-when-cross-origin";

	location /assets {
		try_files $uri =404;
	}

	location ~ ^/protected/(.*) {
		internal;
		try_files /erpnext.local/$1 =404;
	}

	location /socket.io {
		proxy_http_version 1.1;
		proxy_set_header Upgrade $http_upgrade;
		proxy_set_header Connection "upgrade";
		proxy_set_header X-Frappe-Site-Name erpnext.local;
		proxy_set_header Origin $scheme://$http_host;
		proxy_set_header Host $host;

		proxy_pass http://frappe-bench-socketio-server;
	}

	location / {

 		rewrite ^(.+)/$ $1 permanent;
  		rewrite ^(.+)/index\.html$ $1 permanent;
  		rewrite ^(.+)\.html$ $1 permanent;

		location ~* ^/files/.*.(htm|html|svg|xml) {
			add_header Content-disposition "attachment";
			try_files /erpnext.local/public/$uri @webserver;
		}

		try_files /erpnext.local/public/$uri @webserver;
	}

	location @webserver {
		proxy_http_version 1.1;
		proxy_set_header X-Forwarded-For $remote_addr;
		proxy_set_header X-Forwarded-Proto $scheme;
		proxy_set_header X-Frappe-Site-Name erpnext.local;
		proxy_set_header Host $host;
		proxy_set_header X-Use-X-Accel-Redirect True;
		proxy_read_timeout 120;
		proxy_redirect off;

		proxy_pass  http://frappe-bench-frappe;
	}

	# error pages
	error_page 502 /502.html;
	location /502.html {
		root /usr/local/lib/python3.10/dist-packages/bench/config/templates;
		internal;
	}

	

	# optimizations
	sendfile on;
	keepalive_timeout 15;
	client_max_body_size 50m;
	client_body_buffer_size 16K;
	client_header_buffer_size 1k;

	# enable gzip compresion
	# based on https://mattstauffer.co/blog/enabling-gzip-on-nginx-servers-including-laravel-forge
	gzip on;
	gzip_http_version 1.1;
	gzip_comp_level 5;
	gzip_min_length 256;
	gzip_proxied any;
	gzip_vary on;
	gzip_types
		application/atom+xml
		application/javascript
		application/json
		application/rss+xml
		application/vnd.ms-fontobject
		application/x-font-ttf
		application/font-woff
		application/x-web-app-manifest+json
		application/xhtml+xml
		application/xml
		font/opentype
		image/svg+xml
		image/x-icon
		text/css
		text/plain
		text/x-component
		;
		# text/html is always compressed by HttpGzipModule
}

And my NGINX erpnext.subdomain.conf is as follows:

server {
    listen 443 ssl;
    listen [::]:443 ssl;

    server_name erp.*;

    include /config/nginx/ssl.conf;

    client_max_body_size 0;

    # enable for ldap auth (requires ldap-location.conf in the location block)
    #include /config/nginx/ldap-server.conf;

    # enable for Authelia (requires authelia-location.conf in the location block)
    #include /config/nginx/authelia-server.conf;

    location / {
        include /config/nginx/proxy.conf;
        resolver 127.0.0.11 valid=30s;
        proxy_pass http://10.0.0.121:80;
        
    }
}

Please let me know if there’s something obvious I overlooked here.

Thanks,
W