Nginx permission denied error after CSP update

I’m deploying OnlyOffice Document Server with docker.
We run a stack in swarm mode. Everything was fine, until a update in the rules of our enterprise external proxy. Those obliged all requests to be made over https (content security policy). After that, the server started responding with this error:

==> /var/log/onlyoffice/documentserver/nginx.error.log <==
2026/01/21 16:25:36 error 1059#1059: *78 open() "/var/lib/onlyoffice/documentserver/App_Data/cache/files/H9B8MXETXEUCGUH9NMS4/Editor.bin" failed (13: Permission denied), client: 10.0.0.2, server: , request: "GET /cache/files/H9B8MXETXEUCGUH9NMS4/Editor.bin/Editor.bin?md5=ylA2PZhg3vAa39OS4QR26Q&expires=1771607326&filename=Editor.bin HTTP/1.1", host: "onlyoffice_ups", referrer: "https://subdomain.my-site.com/main/docservice/7.0.1-37/web-apps/apps/documenteditor/embed/index.html?_dc=7.0.1-37&lang=pt-BR&customer=ONLYOFFICE&frameEditorId=iframeEditor&compact=true&parentOrigin=https://subdomain.my-site.com"
Content-Security-Policy: Upgrading insecure request ‘http://subdomain.my-site.com/main/docservice/cache/files/H9B8MXETXEUCGUH9NMS4/Editor.bin/Editor.bin?md5=ylA2PZhg3vAa39OS4QR26Q&expires=1771607326&filename=Editor.bin’ to use ‘https’

XHRGET
https://subdomain.my-site.com/main/docservice/cache/files/H9B8MXETXEUCGUH9NMS4/Editor.bin/Editor.bin?md5=ylA2PZhg3vAa39OS4QR26Q&expires=1771607326&filename=Editor.bin
[HTTP/1.1 403 Forbidden 506ms]

	
GET
	https://subdomain.my-site.com/main/docservice/cache/files/H9B8MXETXEUCGUH9NMS4/Editor.bin/Editor.bin?md5=ylA2PZhg3vAa39OS4QR26Q&expires=1771607326&filename=Editor.bin
Status
403
Forbidden
VersionHTTP/1.1
Transferred594 B (146 B size)
Referrer Policystrict-origin-when-cross-origin
DNS ResolutionSystem

    	
    Connection
    	keep-alive
    Content-Encoding
    	gzip
    Content-Type
    	text/html
    Date
    	Wed, 21 Jan 2026 16:25:36 GMT
    Set-Cookie
    	interno_main=rd3999o00000000000000000000ffff0a00aa38o80; path=/; Httponly; Secure
    Set-Cookie
    	TS0160dc65=01648f6ca1729b4323319af637784fa4445d4cdac2201ae3ef02d880f6700a15ece993ceee573201ceea4cb97e66fa0bd7e5739cbf74c162c80dcff268a4c86cc54335cbb6; Path=/; Domain=.subdomain.my-site.com; Secure; HttpOnly
    Transfer-Encoding
    	chunked
    Vary
    	Accept-Encoding
    	
    Accept
    	*/*
    Accept-Encoding
    	gzip, deflate, br, zstd
    Accept-Language
    	en-US,en;q=0.9
    Connection
    	keep-alive
    Host
    	subdomain.my-site.com
    Origin
    	https://subdomain.my-site.com
    Referer
    	https://subdomain.my-site.com/main/docservice/7.0.1-37/web-apps/apps/documenteditor/embed/index.html?_dc=7.0.1-37&lang=pt-BR&customer=ONLYOFFICE&frameEditorId=iframeEditor&compact=true&parentOrigin=https://subdomain.my-site.com
    Sec-Fetch-Dest
    	empty
    Sec-Fetch-Mode
    	cors
    Sec-Fetch-Site
    	same-origin
    User-Agent
    	Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:147.0) Gecko/20100101 Firefox/147.0

I tried to update the stack to use HTTPS in OnlyOffice, as explained [here] (Switching ONLYOFFICE Docs to HTTPS protocol), but couldn’t solve the issue. We still face the same erros above, but now we don’t receive the warning that the request is insecure and would be upgraded.

My Setup:

Docker Stack (swarm):

  • Nginx Proxy

  • OnlyOffice Service

  • Django App (file provider)

This is how the requests are proxied:

[ User ] =HTTPS=> [ External proxy ] =HTTP=> [ Docker Stack (Nginx service) ] =HTTP=> [ Docker Stack (Other services) ]

[ User ] =HTTPS=> [ External proxy ] =HTTP=> [ Docker Stack (Nginx service) ] =HTTPS=> [ Docker Stack (OnlyOffice Service) ]

Stack details:

  • All services are in the same network

  • The nginx proxy the requests

  • The django app stores the docxs and serves them to OnlyOffice

  • The onlyoffice serves the doc editor with the content of the received docx

This is my nginx conf file.

I followed the instructions present here (Common scenario, proxy to local server) for this configs. We serve the OnlyOffice service under the route /main/docservice/

upstream django_ups {
    server django:8000;
}

upstream onlyoffice_ups {
  server 192.168.0.56:88;
}


map $http_x_forwarded_proto $the_scheme {
     default $http_x_forwarded_proto;
     "" $scheme;
}

map $http_x_forwarded_host $the_host {
    default $http_x_forwarded_host;
    "" $host;
}

map $http_upgrade $proxy_connection {
  default upgrade;
  "" close;
}

proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $proxy_connection;
proxy_set_header X-Forwarded-Host $the_host/main/docservice;
proxy_set_header X-Forwarded-Proto $the_scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 500M;

server {
    listen      0.0.0.0:80;
    server_name subdomain.my-site.com;
    server_tokens off;
    root        /usr/share/nginx/html;

    add_header Content-Security-Policy upgrade-insecure-requests;

    error_page 404 /404.html;
        location = /40x.html {
    }

    error_page 500 502 503 504 /50x.html;
        location = /50x.html {
    }

    location = /favicon.ico { access_log off; log_not_found off; }

    location /main/static/ {
        alias /opt/config/main/static/;
    }

    location /main/docservice/ {
        expires -1;
        proxy_pass https://onlyoffice_ups/;
        proxy_http_version 1.1;
        proxy_ssl_verify off;
    }
}

OnlyOffice Docker Image:

  • We are using an official image for enterprise edition, version 7.0.1-37, for which we have a valid license

This is how the OnlyOffice service and the Nginx are configured in my stack:

proxy:
   image: nginx:1.27.0-bookworm
   volumes:
     - ./docker/nginx/common-settings:/etc/nginx/common-settings
     - ./docker/nginx/sites-avaiable:/etc/nginx/sites-avaiable
     - ./docker/nginx/nginx.conf:/etc/nginx/nginx.conf
     - ./docker/nginx/proxy_entrypoint.sh:/docker-entrypoint.d/proxy_entrypoint.sh
     - static_volume:/opt/config/main/static
     - media_volume:/opt/config/main/media
     - ./docker/certs/:/etc/ssl/certs
   ports:
     - target: 80
       published: 80
       protocol: tcp
       mode: host
     - target: 443
       published: 443
       protocol: tcp
       mode: host
   networks:
     - my_net
   env_file:
     - docker/configs/nginx.env
onlyoffice:
    image: onlyoffice/documentserver-ee:7.0.1-37
    restart: always
    env_file:
      - docker/configs/onlyoffice.env
    ports:
      - 88:443
    ulimits:
     nofile:
       soft: 65536
       hard: 65536
    volumes:
      - ./docker/configs/onlyoffice_local-production-linux.json:/etc/onlyoffice/documentserver/local-production-linux.json
      - ./docker/configs/onlyoffice_license.lic:/var/www/onlyoffice/Data/license.lic
      - onlyoffice_db:/var/lib/postgresql
      - ./docker/certs/onlyoffice:/var/www/onlyoffice/Data/certs
    networks:
      - my_net

onlyoffice.env contents:

JWT_ENABLED=true
JWT_HEADER=Authorization
ONLYOFFICE_HTTPS_HSTS_ENABLED=true
ALLOW_META_IP_ADDRESS=true
ALLOW_PRIVATE_IP_ADDRESS=true
USE_UNAUTHORIZED_STORAGE=true
JWT_SECRET=Very-Secure-Secret-123

onlyoffice_local-production-linux.json contents:

{
    "services": {
        "CoAuthoring":{
            "requestDefault": {
                "gzip": false,
                "rejectUnauthorized": false
            }, 
            "request-filtering-agent": {
                "allowPrivateIPAddress": true,
                "allowMetaIPAddress": true
            },
            "callbackBackoffOptions": {
                "retries": 100,
                "timeout":{
                  "factor": 2,
                  "minTimeout": 1000,
                  "maxTimeout": 172800000,
                  "randomize": false
                },
                "httpStatus": "429,500-599"
              },
              "expire": {
                "sessionidle": "20m"
              },
              "utils": {
                "limits_image_types_upload": "jpg;jpeg;jpe;png;gif"
              },
              "server": {
                "limits_image_size": 3145728
              }
        }
    },
    "FileConverter": {
        "converter": {
          "maxDownloadBytes": 314572800
        }
    },
    "license": {
        "warning_limit_percents": 80
    }
}

Update:

Could make the service run again with this:

  1. Rolled back all the https stuff

  2. Access container
    docker exec -it {container_id} bash

  3. Changed configs of nginx, in order to make it user another user:
    nano /etc/nginx/nginx.conf

/etc/nginx/nginx.conf content

# user www-data; # comment this line
user root; # add this
  1. Reload the service
service nginx reload
nginx -t

I still don’t understand why it worked, considering I didn’t messed up with the official container init scripts. How could www-data user lost its access wrights? Still looking for answers.

Hello @lchecon89

You have mentioned an update to an external proxy, possibly it is no longer accepts www-data user to operate?