Meet ONLYOFFICE Docs Cloud, complete office software as a service
Meet ONLYOFFICE Docs Cloud

OnlyOffice 7.2 secure_link_secret error

We have been running Only Office EE without issue for a couple of years through several updates and upgrades. We were running 7.1.1 on NGINX on the AlmaLinux 8 platform.
Last night we upgraded to 7.2 which is usually a very simple problem free process using the DNF linux package manager which executed without issue.

However, NGINX now will not start. The error log shows:

nginx: [emerg] unknown “secure_link_secret” variable

There are only two references to “secure_link_secret”, one where a variable is set in /etc/nginx/conf.d/ds.conf:

set $secure_link_secret verysecretstring;

and one where the variable is used /etc/nginx/includes/ds-docservice.conf:

secure_link_md5 “$secure_link_expires$uri$secure_link_secret”;

Has anyone else experienced this and if so, what is the fix?

Hello @mudslide567
Please point us to Document server installation and update guides which you used.
Also please go to Document server welcome page > is there any error entry? Is it possible to open any file in the integrated example? Please make a screenshot of an error and provide us with whole Document server logs folder. In case of package installation, it’s located here: /var/log/onlyoffice/documentserver/

Also please go to the host and run yum list installed | grep onlyoffice. Please show us the result.

I just found that this may be caused by that you are actually including /etc/nginx/includes/ds-.conf in other files other than default in conf.d folder. Hence it is missing the env with the variable “secure_link_secret” in the files with name of includes/ds-.conf. So just add the line

set $secure_link_secret verysecretstring;

Before where you

  include /etc/nginx/includes/ds-*.conf;

In the including tree of nginx.conf (or whatever configured as the default config file of nginx).

It’s a little bit strange. I have checked /etc/nginx/conf.d/ds.conf file on my test server and secure_link line persists there.
I believe that the issue is related to some difficulties during installation or update steps. But I need to know exact steps to reproduce it.

I had to change the set $secure_link_secret verysecretstring; in the ds.conf $secure_link_secret kkjnjkok1kk1k1nkj1; and 403 went away . I looked at the local.json and seen a new line


“storage”: {

"fs": {

  "secretString": "kkjnjkok1kk1k1nkj1"


The secretstring has been motified for this post server is different just wnated to give an example

That has solved. Thank you!

I have the same problem after upgrading to ONLYOFFICE Document Server 7.2 from older versions, when opening a file in Nextcloud I get:

Screenshot 2022-10-15 at 19-38-07 Documents - Files - Nextcloud

And when saving the ONLYOFFICE settings at I get:

Error when trying to connect (Client error: `GET` resulted in a `403 Forbidden` response:

403 Forbidden

The suggestions above didn’t solve this problem for me, the verysecretstring is contained in these files:

cd /etc/onlyoffice
grep -r to2ie2Ohquee9voh3ahGooph6aiqueeto .
./onlyoffice/documentserver/nginx/ds.conf:  set $secure_link_secret "to2ie2Ohquee9voh3ahGooph6aiqueeto";
./onlyoffice/documentserver/nginx/ds.conf:  set $secure_link_secret "to2ie2Ohquee9voh3ahGooph6aiqueeto";
./onlyoffice/documentserver/nginx/ds.conf:  set $secure_link_secret "to2ie2Ohquee9voh3ahGooph6aiqueeto";
./onlyoffice/documentserver/local.json:          "string": "to2ie2Ohquee9voh3ahGooph6aiqueeto"
./onlyoffice/documentserver/local.json:          "string": "to2ie2Ohquee9voh3ahGooph6aiqueeto"
./onlyoffice/documentserver/local.json:          "string": "to2ie2Ohquee9voh3ahGooph6aiqueeto"
./onlyoffice/documentserver-example/local.json:      "secret": "to2ie2Ohquee9voh3ahGooph6aiqueeto",

There are entries like this in the /var/log/onlyoffice/documentserver/docservice/out.log log:

[2022-10-15T18:36:28.504] [ERROR] [localhost] [3550648349] [vaiChool0tee4_cloud] nodeJS - postData error: url =;data = {"key":"3550648349","status":1,"users":["vaiChool0tee4_cloud"],"actions":[{"type":1,"userid":"vaiChool0tee4_cloud"}],"token":"soa6Ia4aijooniomee3ei4eacaich1ail3sei.eyJrZXkiOiIzNTUwNjQ4MzQ5Iiwic3RhdHVzIjoxLCJ1c2VycyI6WyJvY2xnYnRqYTFnbHJfY2xvdWQiXSwiYWN0aW9ucyI6W3sidHlwZSI6MSwidXNlcmlkIjoib2NsZ2J0amExZ2xyX2Nsb3VkIn1dLCJpYXQiOjE2NjU4NTg5ODgsImV4cCI6MTY2NTg1OTI4OH0.aa6Eer_tei3Iu5aiNie0tie9thieTeheedi7ba8faegho"} Error: Error response: statusCode:403; headers:{"date":"Sat, 15 Oct 2022 18:36:26 GMT","server":"Apache/2.4.54 (Debian)","expires":"Thu, 19 Nov 1981 08:52:00 GMT","pragma":"no-cache","cache-control":"no-cache, no-store, must-revalidate","x-request-id":"ie1seN6iot5voh2ake2ji","content-security-policy":"default-src 'none';base-uri 'none';manifest-src 'self';frame-ancestors 'none'","feature-policy":"autoplay 'none';camera 'none';fullscreen 'none';geolocation 'none';microphone 'none';payment 'none'","x-robots-tag":"none","set-cookie":["oc_sessionPassphrase=Bai5ohyahGeigh4aac1fei8zuvai8eiW8iXaeThoWooghao7Eish1ut1Xesi9esaiquaikao4ohth2pohch9oopohveagah5shutaimeethueh0ohni9juidei3raek8shafouc; path=/; secure; HttpOnly; SameSite=Lax","aeGae0Ai5kaiY=ahBae5FuJ5aiteeg8eeghahphoe; path=/; secure; HttpOnly; SameSite=Lax","__Host-nc_sameSiteCookielax=true; path=/; httponly;secure; expires=Fri, 31-Dec-2100 23:59:59 GMT; SameSite=lax","__Host-nc_sameSiteCookiestrict=true; path=/; httponly;secure; expires=Fri, 31-Dec-2100 23:59:59 GMT; SameSite=strict"],"strict-transport-security":"max-age=630720645;","permissions-policy":"interest-cohort=()","referrer-policy":"no-referrer","x-content-type-options":"nosniff","x-frame-options":"SAMEORIGIN","x-permitted-cross-domain-policies":"none","x-xss-protection":"1; mode=block","upgrade":"h2,h2c","connection":"Upgrade, Keep-Alive","content-length":"27","keep-alive":"timeout=5, max=100","content-type":"application/json; charset=utf-8"}; body:^M
{"message":"Access denied"}
    at Request._callback (/snapshot/server/build/server/Common/sources/utils.js)
    at Request.callback (/snapshot/server/build/server/Common/node_modules/request/request.js:185:22)
    at Request.emit (events.js:400:28)
    at Request.<anonymous> (/snapshot/server/build/server/Common/node_modules/request/request.js:1154:10)
    at Request.emit (events.js:400:28)
    at IncomingMessage.<anonymous> (/snapshot/server/build/server/Common/node_modules/request/request.js:1076:12)
    at Object.onceWrapper (events.js:519:28)
    at IncomingMessage.emit (events.js:412:35)
    at endReadableNT (internal/streams/readable.js:1333:12)
    at processTicksAndRejections (internal/process/task_queues.js:82:21)

The only way I have found to prevent HTTP 403 responses is to comment the following section of the /etc/onlyoffice/documentserver/nginx/includes/ds-docservice.conf file:

  if ($secure_link = "") {
    return 403;

I have tried debugging it by amending the /etc/onlyoffice/documentserver/nginx/includes/ds-docservice.conf file so it reads:

location ~* ^(\/cache\/files.*)(\/.*) {
  alias /var/lib/onlyoffice/documentserver/App_Data$1;
  add_header Content-Disposition "attachment; filename*=UTF-8''$arg_filename";

  secure_link $arg_md5,$arg_expires;
  secure_link_md5 "$secure_link_expires$uri$secure_link_secret";

  if ($secure_link = "") {
    add_header X-ONLYOFFICE-ARG-EXPIRES "$arg_expires";
    add_header X-ONLYOFFICE-ARG-MD5 "$arg_md5";
    add_header X-ONLYOFFICE-SECURE-LINK-EXPIRES "$secure_link_expires";
    add_header X-ONLYOFFICE-SECURE-LINK-SECRET "$secure_link_secret";
    add_header X-ONLYOFFICE-URI "$uri";
    # return 403;

  if ($secure_link = "0") {
    return 410;

And this results in the following headers:

HTTP/1.1 200 OK
Server: nginx
Date: Sat, 15 Oct 2022 16:54:25 GMT
Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.doc
Content-Length: 7859
Last-Modified: Sat, 15 Oct 2022 15:54:24 GMT
Connection: close
ETag: "634ad7b0-1eb3"
X-ONLYOFFICE-ARG-MD5: oC4phu9aeChieS8_Ohl4ahKe
X-ONLYOFFICE-URI: /cache/files/data/conv_check_172363310_docx/output.docx/check_
Accept-Ranges: bytes

So all the variables required for the Nginx ngx_http_secure_link_module module are set, however the secure_link variable is clearly empty (if it wasn’t I wouldn’t get the HTTP headers I added).

The module is compiled into Nginx:

nginx -V 2>&1 | grep --color secure_link       
configure arguments: --with-cc-opt='-g -O2 -ffile-prefix-map=/build/nginx-QeqwpL/nginx-1.18.0=. -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -fPIC' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/ --modules-path=/usr/lib/nginx/modules --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-compat --with-debug --with-pcre-jit --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_v2_module --with-http_dav_module --with-http_slice_module --with-threads --with-http_addition_module --with-http_flv_module --with-http_geoip_module=dynamic --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module=dynamic --with-http_mp4_module --with-http_perl_module=dynamic --with-http_random_index_module --with-http_secure_link_module --with-http_sub_module --with-http_xslt_module=dynamic --with-mail=dynamic --with-mail_ssl_module --with-stream=dynamic --with-stream_geoip_module=dynamic --with-stream_ssl_module --with-stream_ssl_preread_module --add-dynamic-module=/build/nginx-QeqwpL/nginx-1.18.0/debian/modules/http-headers-more-filter --add-dynamic-module=/build/nginx-QeqwpL/nginx-1.18.0/debian/modules/http-auth-pam --add-dynamic-module=/build/nginx-QeqwpL/nginx-1.18.0/debian/modules/http-cache-purge --add-dynamic-module=/build/nginx-QeqwpL/nginx-1.18.0/debian/modules/http-dav-ext --add-dynamic-module=/build/nginx-QeqwpL/nginx-1.18.0/debian/modules/http-ndk --add-dynamic-module=/build/nginx-QeqwpL/nginx-1.18.0/debian/modules/http-echo --add-dynamic-module=/build/nginx-QeqwpL/nginx-1.18.0/debian/modules/http-fancyindex --add-dynamic-module=/build/nginx-QeqwpL/nginx-1.18.0/debian/modules/http-geoip2 --add-dynamic-module=/build/nginx-QeqwpL/nginx-1.18.0/debian/modules/nchan --add-dynamic-module=/build/nginx-QeqwpL/nginx-1.18.0/debian/modules/http-lua --add-dynamic-module=/build/nginx-QeqwpL/nginx-1.18.0/debian/modules/rtmp --add-dynamic-module=/build/nginx-QeqwpL/nginx-1.18.0/debian/modules/http-uploadprogress --add-dynamic-module=/build/nginx-QeqwpL/nginx-1.18.0/debian/modules/http-upstream-fair --add-dynamic-module=/build/nginx-QeqwpL/nginx-1.18.0/debian/modules/http-subs-filter

I’m testing this with Nextcloud running on Debian Bullseye with PHP-FPM 7.4 on one server:

php --version
PHP 7.4.30 (cli) (built: Jul  7 2022 15:51:43) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Zend OPcache v7.4.30, Copyright (c), by Zend Technologies
cat /etc/debian_version 
php occ status
  - installed: true
  - version:
  - versionstring: 24.0.6
  - edition: 
  - maintenance: false
  - needsDbUpgrade: false
  - productname: Nextcloud
  - extendedSupport: false

And ONLYOFFICE running on Debian Bullseye with ONLYOFFICE 7.2.0 on another server:

apt-cache policy onlyoffice-documentserver | head -n7
  Installed: 7.2.0-204
  Candidate: 7.2.0-204
  Version table:
 *** 7.2.0-204 100
        500 squeeze/main amd64 Packages
        100 /var/lib/dpkg/status

Both development servers in question have been built and configured using the Ansible in this repo and the ONLYOFFICE role is here and it is based on these install instructions.

I have checked the clocks on both servers and they match (I have found in the past that if the clock on one server is off it results in one being unable to open documents using ONLYOFFICE via Nextcloud).

If I run the following on the ONLYOFFICE server:

supervisorctl start ds:example

And go to I get the “Download failed” 403 error when opening a document unless the Nginx return 403; line in /etc/onlyoffice/documentserver/nginx /includes/ds-docservice.conf is commented out, when it is commented out everything works without issues.

Does anyone have any suggestions regarding what else can I do to debug this problem?

NOTE all the secure strings in the content I have posted above have been edited so none of them match the actual strings.

I’ve solved the issue after finding this thread, on one server on which I have reinstalled onlyoffice-documentservers the secret string for filesystem access in local.json didn’t match the other secret strings and this can be fixed using the script, perhaps this needs to be documented somewhere?

On other upgraded servers the /etc/onlyoffice/documentserver/local.json didn’t contain the secret string for filesystem access (the same secret string as used elsewhere in the file), for example:

  "storage": {
    "fs": {
      "secretString": "usieh0oeXe7Boo2aey4ieph0iey8paiqu"

Again this can be set using the script, for example: usieh0oeXe7Boo2aey4ieph0iey8paiqu

Perhaps something about this could be added to the troubleshooting or updating documentation?

1 Like

Hello @chris
We are glad that the issue is solved, but your description of the situation is a little bit strange:

the secret string for filesystem access in local.json didn’t match the other secret strings

On other upgraded servers the /etc/onlyoffice/documentserver/local.json didn’t contain the secret string

I believe we have to take a closer look at it. I assume that there was an issue with update process. Would you mind providing us with exact update steps which you have done? Also please let us know your server OS and Document server installation type (docker\package).

Thanks for asking @Alexandre, the server which had a secret string for filesystem access in local.json which didn’t match the other secret strings had been “upgraded” via:

apt purge onlyoffice-documentserver
apt install onlyoffice-documentserver

I did this when trying to solve the 403 errors.

The other servers didn’t have the secret string for filesystem access in local.json and they had been upgraded using:

apt upgrade

All the servers are running Debian Bullseye.

Hello @chris
Did you install mentioned servers manually or via one-click installation script? Please take a look at official update guide Updating ONLYOFFICE Docs for Linux to the latest version - ONLYOFFICE
I believe that issue which you faced is related to your update steps. For example, purge command. In case of deb package installation, there’re a lot of dependencies and I’m not sure that purge can correctly remove all of them.

The production servers were installed using this Ansible role, I only did a apt purge on the development machine when trying to solve the 403 errors.

We didn’t test this installation guide, so I can’t suppose what issues can be faced.
we recommend to use our official regular-tested guides: Installation Guides - Docs - ONLYOFFICE

Thanks @Alexandre, the Ansible role I use is based on the official guides and your Ansible Role: ONLYOFFICE Document Server.

@Alexandre A PR was proposed as we had the same issue with OnlyOfice docker image and found the bug
Could you consider it ?
It seems that the secretString param was never the same as the one put in local.json, thus after each restart we get two different params which caused the 403 error. We overrided both files local.json and ds.conf to make things work as expected and it worked.


Hello @chris

the Ansible role I use is based on the official guides and your Ansible Role: ONLYOFFICE Document Server

Please let me explain in details. We have our official Ansible role here: Ansible Galaxy
The mentioned guide (webarch / ONLYOFFICE Document Server · GitLab) is based on our instructions, but it uses different role.
For example, there are differences with nginx config location in your guide. In our installation, it’s located here: /etc/ngninx/conf.d/ds.conf
But in your guide: tasks/nginx.yml · master · webarch / ONLYOFFICE Document Server · GitLab
I assume that this is the reason of the issue which you faced.
In general, we recommend to use our official guides.

Second part of message is for @ahamdi
First of all I want to say hello on this forum.
I have checked mentioned PR. It is closed by topic starter. It looks like there’s no issue.
If I’m wrong, please provide us with details.

1 Like

I know, that is the same one as the one I linked to.

I know, I wrote it.

No that isn’t the cause of the missing secret string for storage access but thanks for your time.

Hello @Alexandre ,
thank you for your reply
We moved to use the docker param SECURE_LINK_SECRET which worked as expected. Our issue was just when we overrided the file local.json without overriding the NGING conf file ds.conf
I may just confirm that the 403 error is related to the difference between both values of SECURE_LINK_SECRET between ds.conf and local.json , maybe this helps someone who got the same issue.


Yes, the different data (secure link) in mentioned files provokes described issue.

Exactly this fixes the problem !