Nextcloud Office: fonts uploaded via Extra Fonts never appear in Collabora editor

Support intro

Sorry to hear you’re facing problems. :slightly_frowning_face:

The community help forum (help.nextcloud.com) is for home and non-enterprise users. Support is provided by other community members on a best effort / “as available” basis. All of those responding are volunteering their time to help you.

If you’re using Nextcloud in a business/critical setting, paid and SLA-based support services can be accessed via portal.nextcloud.com where Nextcloud engineers can help ensure your business keeps running smoothly.

Getting help

In order to help you as efficiently (and quickly!) as possible, please fill in as much of the below requested information as you can.

Before clicking submit: Please check if your query is already addressed via the following resources:

(Utilizing these existing resources is typically faster. It also helps reduce the load on our generous volunteers while elevating the signal to noise ratio of the forums otherwise arising from the same queries being posted repeatedly).

Some or all of the below information will be requested if it isn’t supplied; for fastest response please provide as much as you can. :heart:

The Basics

  • Nextcloud Server version (e.g., 29.x.x):
    • 34.0.1
  • Operating system and version (e.g., Ubuntu 24.04):
    • Docker host on Linux (containerized deployment — Nextcloud itself runs via the official nextcloud:34.0.1 Docker image, Debian-based)
  • Web server and version (e.g, Apache 2.4.25):
    • Apache 2.4.67 (Debian) — bundled in the official Nextcloud image
  • Reverse proxy and version _(e.g. nginx 1.27.2)
    • Traefik v3.7.8
  • PHP version (e.g, 8.3):
    • 8.5.8
  • Is this the first time you’ve seen this error? (Yes / No):
    • Yes
  • When did this problem seem to first start?
    • Noticed after uploading fonts via Administration → Nextcloud Office → Extra Fonts; not tied to an upgrade, appears to be a pre-existing bug in this Collabora build.
  • Installation method (e.g. AlO, NCP, Bare Metal/Archive, etc.)
    • Docker Compose (official nextcloud image + separately-hosted collabora/code:26.04.2.3.1 container, connected via WOPI/richdocuments “use your own server” — not the built-in CODE server, not AIO)
  • Are you using CloudfIare, mod_security, or similar? (Yes / No)
    • No (Traefik reverse proxy with Let’s Encrypt, no WAF/CDN in front)

Summary of the issue you are facing:

Custom fonts uploaded via Administration → Nextcloud Office (richdocuments 11.0.1) → Extra Fonts never appear in the Collabora Online editor’s font picker, even though remote_font_config.url is correctly configured and Nextcloud is serving fonts.json
and the individual font files correctly (verified with curl, valid TLS, no auth required, correct content-type/bytes). Root cause found by inspecting the Collabora container directly (see below) — this is a coolwsd bug, not a Nextcloud/richdocuments
issue, but posting here first since Collabora’s own forum may point back to richdocuments, and wanted to confirm we’re not missing an obvious richdocuments-side config step.

Steps to replicate it (hint: details matter!):

  1. Upload one or more .ttf/.otf fonts via Administration → Nextcloud Office → Extra Fonts.

  2. Confirm the banner/instructions to set https://<domain>/apps/richdocuments/settings/fonts.json as the remote_font_config.url in Collabora’s coolwsd.xml (or via --o:remote_font_config.url=… command-line override, which is what we used, to avoid the “mounting coolwsd.xml breaks container startup” issue covered in richdocuments#2763 ( Custom fonts for built-in Nextcloud Office · Issue #2763 · nextcloud/richdocuments · GitHub )).

  3. Restart the Collabora container

  4. Open any document in Nextcloud Office and search the font name in the font picker. It never appears.

  5. Inspecting the running Collabora container shows the font files do download successfully — they land as hash-named .ttf files directly in /opt/cool/child-roots/<jail-id>/tmp/incoming/. But coolwsd’s own startup log shows it explicitly creating /opt/cool/child-roots/<jail-id>/tmp/incoming/fonts/ as the expected destination — and that subdirectory is empty. The downloaded files land one directory level too shallow, so whatever step registers them with LOKit never finds them.

Log entries

Nextcloud

(nothing relevant appears in nextcloud.log for this — the failure is entirely on the Collabora/coolwsd side, not surfaced to Nextcloud at all)

Configuration

occ app:list shows richdocuments: 11.0.1. Collabora connected as an external WOPI server, not the built-in CODE server.

Hi @federatedcarly,

I use Collabora Office as a Debian package—running on bare metal, not in a container.
The fonts have worked for me in the past. Fonts I added a long time ago are still there, even though they are located in the directory you described (one level below the /fonts subdirectory). Newly added fonts do show up in that directory, but they only appear in the font picker after restarting coolwsd—in my case, by running systemctl restart coolwsd. In your case, I would simply try restarting the Docker container.
The directory you mentioned is purely virtual and is completely recreated every time the system restarts. So, there is no point in trying to edit anything there.

h.t.h.


ernolf

That’s helpful context on the directory being ephemeral. One data point that doesn’t quite line up though: in our case, we restarted the Collabora container immediately after uploading the fonts, and they still didn’t appear in the font picker afterward. Per your explanation that restart alone should be enough, so something else seems to be going on for us. We’re running the Docker image (collabora/code:26.04.2.3.1, the newer Nix-built variant), not the bare-metal Debian package. Wondering if that’s the actual differentiator, since we separately found this image’s /var/cache/fontconfig never gains new entries even across a restart. Does your Debian package setup do anything at startup (a fc-cache run, etc.) that the Docker image might be skipping?

Hi @federatedcarly,

no, my Debian setup runs no fc-cache at startup, and I don’t think fontconfig is where the problem is. I checked on my machine: the fonts I uploaded show up in neither /var/cache/fontconfig nor the cool user’s own cache, yet they work fine. Collabora brings its own fontconfig and loads these uploaded fonts by itself, so an empty cache is normal, mine is empty too.

Here is the part that I think matters for you. When I add a new font, it appears in that tmp/incoming folder almost immediately, but it is not in the font picker yet. It only shows up in the picker after I run systemctl restart coolwsd. So on my side the restart is exactly the step that brings the already-downloaded font into the picker. You wrote that you did restart the container and it still didn’t show up, so for you it is precisely that step that fails, not the download and not fontconfig. The file arrives, coolwsd just never registers it on your Nix-built image.

coolwsd keeps no local copy by the way, it re-fetches the fonts from Nextcloud on every start and the tmp folder is rebuilt each time, so docker restart (or docker compose restart) of the Collabora container is the right equivalent of my systemctl restart coolwsd. If even that doesn’t bring the font into the picker, this is really a coolwsd / Nix-image issue rather than anything on the richdocuments side, and the Collabora Online people would be the ones to ask why that build doesn’t register the downloaded fonts.

h.t.h.


ernolf

Thanks again for going back and forth with me on this, it really helped narrow things down. I wanted to share what I found after digging in a bit more and see what you think.

I bumped coolwsd’s logging up to trace and re-tested with remote_font_config running on its own, with no other font workarounds. That confirmed things are working exactly how you described. Fonts download fine, and coolwsd sends an explicit addfont <path> call directly into LOKit for each one. So no issue there, and you were right that everything gets re-fetched on restart rather than cached locally.

What I ran into seems to be related to how the jail (chroot) is set up for each Kit process in this image. The fonts download into .../tmp/incoming/, but the /tmp directory inside the chroot actually comes from a different path, tmp/cool-<jailId>/, tied to the specific kit instance. I verified this by pulling that directory directly with docker cp. It only had user/, home/, and some lock files, with no incoming/ and no symlink to it either.

So the path that coolwsd passes to LOKit does not appear to be accessible from inside the sandboxed process. That makes it look like the failure is happening at the registration step, not during download and not in fontconfig.

I also ruled out a couple of other possibilities along the way. The kit pool settles a few seconds after restart, and the final kit spawned after all font registrations finish still does not see the fonts, so it does not seem to be a startup race. I also tested with a completely fresh document opened well after everything settled, so it does not seem to be browser or session caching either.

This made me wonder if it is something specific to how this Docker image, collabora/code:26.04.2.3.1, the newer Nix-built one, builds its jails. Maybe that is why your bare-metal Debian setup does not hit this, if it is exposing tmp/incoming or more of /tmp inside the chroot.

This is excellent work, you have pinned it down exactly. The addfont <path> goes out, but if that path lives in tmp/incoming/ while the jail’s /tmp is bind-mounted from tmp/cool-<jailId>/ with nothing linking the two, then LOKit inside the chroot simply cannot see the file. That is the registration step failing, precisely where it looked like it would, and your docker cp of the jail is the proof.

It also explains why bare-metal does not hit it. There are jails there too, my logs show the same JailUtil.cpp chroot setup, but the font in tmp/incoming is evidently reachable from inside the Kit, since the picker does get it after a restart. So the only thing that differs is how that image assembles the jail’s /tmp, exactly as your trace shows.

One note on the issue you filed, nextcloud/richdocuments#5933: whatever the exact cause turns out to be, it is not a richdocuments matter. richdocuments is only the Nextcloud-side app, it serves fonts.json and the font files over HTTP and nothing more. It has no say in how coolwsd builds the Kit jail or what gets mounted into the chroot. That is all coolwsd / LOKit, i.e. the CollaboraOnline/online codebase, where the JailUtil / chroot logic lives.

Either way it is not richdocuments, so please close nextcloud/richdocuments#5933. That repo cannot act on a coolwsd jail bug, and leaving it open only adds noise to the wrong tracker.

Where it should go instead depends on one thing worth pinning down: where does your collabora/code:26.04.2.3.1 actually come from? If it is the stock image pulled straight from Docker Hub, then CollaboraOnline/online is the place, just open it fresh over there with the same write-up. But you called it “Nix-built”, and the only Nix build in the Collabora org I can find is CollaboraOnline/nix-build-support, whose own README says plainly it is community-supported and not to be used in production. If your image was built that way rather than pulled from Docker Hub, the jail /tmp layout could well be an artifact of that build, and then that is where it belongs.

h.t.h.


ernolf

Ahh got it, that makes total sense, and thanks for calling that out.

I double-checked the image provenance properly and can confirm this is the official collabora/code:26.04.2.3.1 straight from Docker Hub, not nix-build-support or anything custom. The RepoDigest matches exactly what’s published upstream.

I’ll go ahead and open a new issue on CollaboraOnline/online with the same write-up and close the richdocuments one since you’re right that it’s clearly outside that scope.