Cannot open Seadoc document, nor crate a wiki page

I can’t open a Seadoc document or create a wiki page.
After creating a new Seadoc file, when I try to open it, I get the error message Load doc content error.

After creating a new wiki, I want to add a page, but I get the error message Internal Server Error.

I found something about it here [bug] Internal Server Error while creating page in wiki · Issue #2876 · haiwen/seafile · GitHub. But even though I did all that, my problem still persists.
The error log from the Seadoc container shows the following:

CRITICAL:root:SDOC_DIR is not set
seadoc | Traceback (most recent call last):
seadoc | File “/opt/sdoc-server/sdoc-server-1.0.4/seadoc-converter/seadoc_converter/main.py”, line 3, in
seadoc | import config
seadoc | File “/opt/sdoc-server/sdoc-server-1.0.4/seadoc-converter/seadoc_converter/config.py”, line 24, in
seadoc | raise RuntimeError(‘SDOC_DIR is not set’)
seadoc | RuntimeError: SDOC_DIR is not set
seadoc | server is serve on http://127.0.0.1:7070
seadoc | [2025-02-13 11:59:50] Start seadoc_converter/main.py
seadoc | CRITICAL:root:SDOC_DIR is not set
seadoc | Traceback (most recent call last):
seadoc | File “/opt/sdoc-server/sdoc-server-1.0.4/seadoc-converter/seadoc_converter/main.py”, line 3, in
seadoc | import config
seadoc | File “/opt/sdoc-server/sdoc-server-1.0.4/seadoc-converter/seadoc_converter/config.py”, line 24, in
seadoc | raise RuntimeError(‘SDOC_DIR is not set’)

I don’t know how to investigate this error message. I don’t know where I missed something in the documentation.

I am not using Caddy, but NGINX not installed via Docker.
In a test environment with Caddy, however, I get exactly the same errors in the Seadoc container.

We have fixed the issue with the 1.0-latest image. Please re-pull the image and then start SEADOC, docker pull seafileltd/sdoc-server:1.0-latest

Yes, the “SDOC_DIR is not set” error has disappeared, but the problems remain. I can neither open a Seadoc file nor create a wiki page. I still get the same error messages in both cases as mentioned above.

If there is no more error in the sdoc-server.log and seahub.log, you can find the error in the browser console. For example, open DevTools in Chrome browser, switch to the console and Network tabs.

Usually, this problem may be caused by the domain name or the reverse proxy.

The domain name, yes, that was my mistake. To test, I usually just make an entry in the /etc/hosts file, but that wasn’t enough in this case, I have to enter the host in the DNS.

Now I’m one step further, the document opens, but after that nothing works. When I enter data, it isn’t saved.

I found what I was looking for in the logs.
[source ip addr] [17/Feb/2025:10:51:46 +0100] “GET /socket.io/?sdoc_uuid=59bca42d-c1dd-4165-8b58-6359ab246cd9&EIO=4&transport=polling&t=PKJKYc7 HTTP/1.1” 403 83 “http://seafile12-test.domain.tld/lib/6a70581b-d9db-4a0f-937b-293632ede8d5/file/test.sdoc” “Mozilla/5.0 (X11; Linux x86_64; rv:135.0) Gecko/20100101 Firefox/135.0” 0.002

So there is a status code 403. This is continuously generated as soon as the document is open, i.e. before I try to write anything.

From Chromium’s DevTools:
viewFileSdoc.a0dc04d8.js:2
GET http://seafile12-test.betschart-it.ch/socket.io/?sdoc_uuid=59bca42d-c1dd-4165-8b58-6359ab246cd9&EIO=4&transport=polling&t=PKey_VC 403 (Forbidden)
viewFileSdoc.a0dc04d8.js:2 sdoc:socket-client connect_error. +15ms
viewFileSdoc.a0dc04d8.js:2 sdoc:socket-client reconnect_error. +0ms
viewFileSdoc.a0dc04d8.js:2 sdoc:socket-client reconnect_attempt. 137 +5s

If I change the location line of socket.io in the Nginx configuration file so that it ends with /, the error 403 disappears. It then returns the status code 200, but it doesn’t change the fact that Seadoc cannot save.

Or is it perhaps impossible to work with Seadoc via HTTP? So far I have not obtained certificates until now.

We explained the architecture of how SeaDoc work in SeaDoc Integration - Seafile Admin Manual and how to debug issues.

It is better to use a standard deployment to avoid network issues.

The document in your link does not mention whether HTTPS is mandatory or not. However, https is specified when defining the SEADOC_SERVER_URL variable. This variable is not included in the .env file that can be downloaded. This is not explained clearly enough for me.

I cannot work with Caddy, I have other Docker containers running on the system, so I use NGINX as a reverse proxy for all containers. I cannot use ports 80 and 443 for Seafile alone.

But the big frustration is that it does not work in the recommended standard deployment either. So even with Caddy and only the most necessary adjustments in the .env file were made. Then not even an empty SDOC file could be loaded. After a long loading time, I only see this error in the Chromium DevTools:
Failed to load resource: the server responded with a status of 504 ()

I wouldn’t care about the SDOC server, but I built a wiki for a customer. With Seafile 12, Seadoc is therefore required.

1 Like

I found the error. In the administration manual, under Setup, use other reverse proxy, there is a code example for an Nginx server. There is one slash too much in the proxy_pass for socket.io.

I noticed this when I studied the example for a Seadoc server on another server.

Tell me to use a standard installation, but at the same time write the documentation incorrectly! It has to be written in such a way that I don’t have to try and see whether there is one slash too many somewhere or not. Shame on you!

1 Like

Hello, one issue I have with container setup, but using systemd quadlet to run in rootless podman.

But anyway, my question is how do the systems communicate with each other directly? Because within the network, they can communicate lets say http://seafilehttp://seadoc

But the browser should access the services as https://seafile.example.com and https://seafile.example.com/sdoc-server

From within the container private network they cannot even access the reverse proxy to reach each other with the full domain name.

So I have setup in seafile server config the full domain “https://seafile.example.com/sdoc-server” and in seadoc I have set SEAHUB_SERVICE_URL=http://seafile

I see no errors in the seadoc logs but I see “Load doc content error” in browser trying to open a new sdoc file.

Also in browser console I see

GET https://seafile.example.com/sdoc-server/api/v1/docs/66d458e7-1ce7-4847-a0af-f90fa7e1006a/ [HTTP/2 404 7ms]

I believe my proxy redirects https://seafile.example.com/sdoc-server/ to the root of seadoc and /socket.io to /socket.io

Any idea where might be the issue? Thank you!

Below is the failed request in browser console:

{
  "message": "Request failed with status code 404",
  "name": "AxiosError",
  "stack": "G@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:4342276\nTe@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:4353767\nv@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:4358075\nEventHandlerNonNull*86425/Le</<@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:4358334\n86425/Le<@https://seafile.example.com/media/assets/frontend/static/js/...cut because of messaage size limit...\nbu@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3578609\n38345/Xa/<@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3528161\n31761/t.unstable_runWithPriority@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3891454\nWa@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3527938\nXa@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3528108\nqa@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3528041\nmu@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3576083\nxi@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3547696\n28321/H/</<@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3611732\nt@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3604783\n94449/value/<@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3047777\nvalue@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3047754\n94449/value/l/<@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3076273\n94449/value/a/</<@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3078155\n94449/value/a/<@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3078204\n94449/value/<@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3070201\nvalue@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3069717\n94449/value/<@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3071676\n94449/value/<@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3070625\n35740/value/<@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3044889\n35740/d/o.onreadystatechange@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3043419\nEventHandlerNonNull*d@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3043368\nvalue@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3044628\nvalue@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3044554\nvalue@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3070536\nvalue@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3071439\n94449/value/<@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3071127\nvalue@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3071104\nvalue@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3071182\nvalue@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3077032\nvalue@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3080004\nN@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3604642\n28321/H/<@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3611714\nH@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3611688\no@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3612150\nsi@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3542369\nXs@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3594703\nxu@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3581951\nNu@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3581879\nSu@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3581740\nbu@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3578706\n38345/Xa/<@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3528161\n31761/t.unstable_runWithPriority@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3891454\nWa@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3527938\nXa@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3528108\nqa@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3528041\nju@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3587844\n31761/t.unstable_runWithPriority@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3891454\nWa@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3527938\nPu@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3587119\n38345/Mu/<@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3587030\nP@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3890514\n31761/b.port1.onmessage@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3889236\nEventHandlerNonNull*31761@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3889160\nn@https://seafile.example.com/media/assets/frontend/static/js/runtime.8e8ba7d3.js:1:147\n75340@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3892102\nn@https://seafile.example.com/media/assets/frontend/static/js/runtime.8e8ba7d3.js:1:147\n38345@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3483074\nn@https://seafile.example.com/media/assets/frontend/static/js/runtime.8e8ba7d3.js:1:147\n17119@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:3601833\nn@https://seafile.example.com/media/assets/frontend/static/js/runtime.8e8ba7d3.js:1:147\n57522@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:1017243\nn@https://seafile.example.com/media/assets/frontend/static/js/runtime.8e8ba7d3.js:1:147\n@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:4926043\nt@https://seafile.example.com/media/assets/frontend/static/js/runtime.8e8ba7d3.js:1:6757\n@https://seafile.example.com/media/assets/frontend/static/js/viewFileSdoc.db4ce4b9.js:2:73\n",
  "config": {
    "transitional": {
      "silentJSONParsing": true,
      "forcedJSONParsing": true,
      "clarifyTimeoutError": false
    },
    "adapter": [
      "xhr",
      "http",
      "fetch"
    ],
    "transformRequest": [
      null
    ],
    "transformResponse": [
      null
    ],
    "timeout": 0,
    "xsrfCookieName": "XSRF-TOKEN",
    "xsrfHeaderName": "X-XSRF-TOKEN",
    "maxContentLength": -1,
    "maxBodyLength": -1,
    "env": {},
    "headers": {
      "Accept": "application/json, text/plain, */*",
      "Authorization": "Token REDACTED"
    },
    "method": "get",
    "url": "https://seafile.example.com/sdoc-server/api/v1/docs/55d418e7-1ce7-4847-a0af-f90fa7e1006a/",
    "allowAbsoluteUrls": true
  },
  "code": "ERR_BAD_REQUEST",
  "status": 404
}

After a little fiddling with the proxy the seadoc server log started to show:

[2025-04-21 17:45:15] [ERROR] document-controller.js[74] - Load test.sdoc(55d418
e7-1ce7-4847-a0af-f90fa7e1006a) from https://seafile.example.com/seafhttp/files
/938cfa8f-39f5-45aa-a815-adf7bac18932/test.sdoc error

What could that mean?

If I put this URL in my browser, it does open. But shouldn’t seadoc get the file from SEAHUB_SERVICE_URL? Because as I wrote already, it is set to SEAHUB_SERVICE_URL=http://seafile