404 Not Found on Private Files

I am having an issue where I cannot view a private file attached by another user even though I am logged in?

I am using the Administrator account and still can’t see anything. I get a 404 Not Found error when I click on the attachment. I unchecked private from the file and I can finally see it. It doesn’t sound like a permission issue but rather a nginx issue?

This is my nginx.conf

# Upstream configurations
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;
}

# HTTP Server Block (Port 80)
server {
	listen 80;
	listen [::]:80;
	server_name lech.erpnext.test.lan lech.erpnext.lan;

	root /home/frappeadmin/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;
		add_header Cache-Control "max-age=31536000";
	}

	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 $host;
		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 /$host/public/$uri @webserver;
		}

		try_files /$host/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 $host;
		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;
	}

	# Redirect all HTTP to HTTPS
	error_page 502 /502.html;
	location /502.html {
		root /usr/local/lib/python3.12/dist-packages/bench/config/templates;
		internal;
	}

	return 301 https://$host$request_uri;
}

# HTTPS Server Block (Port 443)
server {
	listen 443 ssl;
	server_name lech.erpnext.test.lan lech.erpnext.lan;

	ssl_certificate /home/frappeadmin/frappe-bench/sites/ssl/nginx-selfsigned.crt;
	ssl_certificate_key /home/frappeadmin/frappe-bench/sites/ssl/nginx-selfsigned.key;

	ssl_protocols TLSv1.2 TLSv1.3;
	ssl_ciphers HIGH:!aNULL:!MD5;

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

	location /assets {
		try_files $uri =404;
		add_header Cache-Control "max-age=31536000";
	}

	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 $host;
		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 /$host/public/$uri @webserver;
		}

		try_files /$host/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 $host;
		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.12/dist-packages/bench/config/templates;
		internal;
	}
}

Solved by properly setting up SSL with multi-tenant mode on. I had a manual configuration for my SSL and didn’t rely on the bench commands to set the ssl certs and key for a specific site originally. Here are some steps if anyone encounters an issue

# ERPNext SSL Setup Commands for DNS Multitenant Mode

## Step 1: Set SSL Certificate and Key Paths in ERPNext

cd /path/to/your/frappe-bench

# Set SSL certificate for your site
bench set-ssl-certificate yoursite.domain.com /path/to/ssl/certificate.crt

# Set SSL private key for your site  
bench set-ssl-key yoursite.domain.com /path/to/ssl/private.key

Step 2: Ensure DNS Multitenant Mode is Enabled

# Enable DNS multitenant mode (if not already enabled)
bench config dns_multitenant on

Step 3: Generate the Proper ERPNext Nginx Configuration

# Generate nginx config with proper SSL and multitenant settings
bench setup nginx --yes

Step 4: Reload Nginx

# Test the configuration first
sudo nginx -t

# If test passes, reload nginx
sudo systemctl reload nginx

Step 5: Clear Cache and Restart ERPNext

# Clear ERPNext cache
bench --site yoursite.domain.com clear-cache

# Restart ERPNext
bench restart

Take this as a lesson to always do it the right way the first time. It would have worked had I did it properly!

1 Like