Why to read this article
If you are using InDesign Server on Censhare Cloud or run InDesign Server in a multi-tenant environment, this article applies to you. Font conflicts in shared environments can silently cause incorrect layouts and wrong PDF output. These issues are difficult to diagnose. Font isolation helps you to prevent this.
Overview
The Censhare Render Client supports per-job font isolation for Adobe InDesign Server. The feature prevents cross-tenant font conflicts in shared rendering environments. These are typically Censhare Cloud deployments where a single InDesign Server instance renders jobs for multiple tenants from a shared font pool.
Why font isolation is required
InDesign resolves fonts primarily by PostScript name, not by file name. If two tenants maintain different versions of the same font that share the same PostScript name in a shared pool, InDesign might load an arbitrary version when opening a document. This produces layout deviations and incorrect PDF output.
Example:
Fonts/
tenantA/
fontB-v1 (PostScript name: "FontB-Regular")
tenantB/
fontB-v2 (PostScript name: "FontB-Regular")
If both directories are connected to InDesign as a single global font pool, a tenantA job may accidentally render with tenantB's font version.
How font isolation solves the problem
Font isolation uses Adobe's native "Document Fonts" mechanism: If a folder named Document Fonts exists next to an InDesign document, InDesign loads fonts from that folder before falling back to globally installed fonts.
The Censhare Render Client creates a fresh, job-specific Document Fonts folder for every render job and populates it with hardlinks to the correct tenant's fonts only. Font resolution becomes tenant-specific, deterministic, and independent of the shared global pool.
How it works
For every render job:
-
The command sequence arrives at the Censhare Render Client. If SetupDocumentFontsCommand is not already present in the sequence, it is automatically inserted as the first command. If multiple SetupDocumentFontsCommand instances are present, only the first runs; each subsequent instance is skipped with a warning in the log.
-
The tenant ID is resolved from the OS username (via configurable regex).
-
The tenant font index (font-index.xml) is checked for freshness and rebuilt if stale.
-
A job-specific working directory is created under
<working-directory>/<job-uuid>/, and aDocument Fontssubfolder is created inside it. -
Fonts are hardlinked into
Document Fonts:-
Link-all mode (small font pools): all tenant fonts are linked.
-
Detection mode (large font pools): The Censhare Render Client opens each participating document, extracts the PostScript names actually used, and links only those fonts.
-
-
InDesign opens the document from the working directory. It finds the job-specific
Document Fontsfolder next to the document and uses it for font resolution. -
After the job completes, the working directory (including the hardlink folder) is deleted. Original fonts in the tenant pool remain untouched.
Prerequisites
-
Censhare Render Client uses Adobe InDesign Server for rendering.
-
One Censhare Render Client per tenant, running under a dedicated OS user account per tenant. This is how the feature identifies the tenant: It uses the OS username of the Censhare Render Client process. In the Censhare Cloud platform this is the standard deployment model. On-premise installations do not necessarily follow this pattern. In that case, the feature can still be used, but the deployment must be configured: Each Censhare Render Client instance runs under an OS account whose name can be mapped to the correct tenant directory, directly or via the configured regex. For more information, see Tenant ID Resolution.
-
A shared tenant font pool reachable on the local filesystem of the Censhare Render Client host: either locally stored or a locally mounted file share.
-
Tenant subdirectory naming: the tenant-specific subdirectory inside
font-base-directorymust either match the OS user name: The login name of the Render Client account can match directly. Or, it can be derivable from it via the configured regex expression. See Tenant ID Resolution for the exact mechanics. -
The working directory and the tenant font directory must reside on the same filesystem volume. Reason: Hardlinks cannot span volumes.
-
Required file permissions on the Censhare Render Client host:
-
Traverse/read on
font-base-directory. This is required to reach the tenant subdirectory. -
Read and write on the tenant's own subdirectory (recursively).
-
Read and write on the working directory.
-
Tenant font pool layout
The tenant font pool is a shared directory containing one subdirectory per tenant. Each tenant directory holds the tenant's font files plus an auto-generated index file.
The directory structure:
<font-base-directory>/
tenantA/
font-index.xml (auto-generated; do not edit)
font-index.xml.bak (transient — exists only during a rebuild)
Helvetica/
HelveticaNeue-Bold.otf
HelveticaNeue-Regular.otf
Minion/
MinionPro-Regular.otf
tenantB/
font-index.xml
...
Supported font file formats
All file-extension matching is case-insensitive. Font files are discovered recursively.
|
Extension |
Format |
|---|---|
|
.ttf |
TrueType |
|
.otf |
OpenType (CFF) |
|
.ttc |
TrueType Collection |
|
.otc |
OpenType Collection |
|
.pfa |
PostScript Type 1 (ASCII) |
|
.pfb |
PostScript Type 1 (Binary) |
Nested directories
Tenant subdirectories may use arbitrarily deep, freely chosen folder structures. Fonts do not need to be stored flat, and no particular layout is required. The Censhare Render Client discovers font files recursively and does not care how they are grouped. Administrators can organize each tenant's fonts according to their own conventions (by family, by foundry, by project, etc.).
The relative structure below each tenant directory is mirrored 1:1 inside the per-job Document Fonts folder. Two fonts with the same base file name in different subdirectories therefore do not collide.
Index and backup files
-
font-index.xmlis created and maintained automatically by the Censhare Render Client. Do not edit or delete it manually. Whenever the contents of the tenant font directory change, the Censhare Render Client detects the change on the next job and rebuilds the index automatically. Changes can be that fonts are added, removed, renamed, moved between subdirectories, or modified. Censhare Render Client uses fingerprints of relative paths, file sizes, and modification timestamps to detect changes.
Administrators do not need to delete the index after updating the tenant font pool. If the file is nevertheless missing, the rebuild still happens automatically. But, it takes time (roughly a few seconds per 1,000 fonts) and this time is added to the runtime of the first affected job. -
font-index.xml.bakis transient: It appears only while a rebuild is in progress. On rebuild success, it is deleted. If the rebuild fails, it is renamed back tofont-index.xml. This way, the previous index remains usable.
Configuration
The Font isolation is configured in the Censhare Render Client preferences file (javarender-preferences.xml) that is stored on Censhare Server.
Two XML tags are part of the configuration:
-
<render-client> defines general render-job settings that are independent of font handling.
-
<document-fonts> defines settings for the per-job font isolation feature.
For a minimal required configuration, see Minimal configuration.
XML tag: render-client
The following attributes can be set, for example:
<render-client working-directory="D:\RenderWork"/>
|
Attribute |
Description |
|---|---|
|
working-directory |
Local working directory for render jobs. Each job creates its own subdirectory: If the attribute is empty or absent, |
Example entry:
<render-client working-directory="D:\RenderWork"/>
XML tag: document-fonts
The following attributes can be set, for example:
<document-fonts
enabled="true"
font-base-directory="\\fileserver\Fonts"
font-detection-threshold="30"
tenant-id-pattern="(.*)"
tenant-id-replacement="$1"
index-creation-base-timeout-ms="60000"
index-creation-per-font-timeout-ms="20"
index-wait-grace-ms="10000"/>
|
Attribute |
Default |
Description |
|---|---|---|
|
enabled |
false |
Switches font isolation on or off. By default, it is set to false! Administrators must explicitly enable font isolation by setting enabled="true". This applies to both fresh installations and upgrades: if the To enable it, the XML tag must be added with |
|
font-base-directory |
(empty) |
Root directory of the shared tenant font pool. When font-base-directory is empty, the feature is inactive for all jobs. |
|
tenant-id-pattern |
(.*) |
The regex is applied to the OS username to derive the tenant directory name. |
|
tenant-id-replacement |
$1 |
Stores the replacement string of the regex match: |
|
font-detection-threshold |
30 |
Tenant font count at or above which the detection mode is used. Below this value, the link-all mode is used. |
|
index-creation-base-timeout-ms |
60000 |
Fixed base timeframe (ms) of the index rebuild timeout. |
|
index-creation-per-font-timeout-ms |
20 |
Per-font timeframe (ms) of the index rebuild timeout. Calculation of the total timeout for creation xxx = |
|
index-wait-grace-ms |
10000 |
Extra grace timeframe (ms) that is added on top of the creation-timeout formula when a job waits for a concurrent rebuild. |
Requirements to activate font isolation
To use font isolation, the following conditions must be fulfilled:
-
enabled="true"is set explicitly in the <document-fonts> XML tag. -
font-base-directoryattribute is set and exists on the filesystem. -
The resolved tenant font directory (
<font-base-directory>/<tenant-id>) exists.
If condition 1 is not met, the feature is silently inactive: Jobs use the global font pool exactly as before. Reasons can be:
-
The enabled attribute missing or set to false.
-
The <document-fonts> XML tag itself is missing.
If condition 1 is met but condition 2 or 3 is not, the job fails immediately with a clear error message. This is intentional: once an administrator has opted in with enabled="true", the configuration is treated as a strict contract. A silent fallback to the global font pool would mask tenant-isolation misconfiguration, for example wrong path, missing tenant subdirectory, or unmounted share. The admin would not be informed that the font isolation is not activated.
If you want jobs to run without font isolation, set enabled="false" explicitly.
Minimal configuration
If you just want to turn the feature on, only a small number of attributes must be set. Everything else can stay at its default settings:
<render-client
working-directory="D:\RenderWork"/>
<document-fonts
enabled="true"
font-base-directory="\\fileserver\Fonts"/>
Required XML tags and attributes:
-
render-client working-directory XML tag:
-
working-directory attribute
-
-
document-fonts XML tag
-
enabled attribute
-
font-base-directory attribute
-
Conditionally required:
-
document-fonts tag:
-
document-fonts tenant-id-pattern/tenant-id-replacement attributes
-
These attributes are only required if the tenant subdirectory name does not match the OS username of the Censhare Render Client account directly. For more information, see Tenant ID Resolution.
-
Tenant ID resolution
The Censhare Render Client identifies the tenant from the OS username of its own process and maps it to a tenant subdirectory under font-base-directory.
This assumes that each Censhare Render Client instance runs under an OS account which name corresponds to exactly one tenant. In the Censhare Cloud platform, this is the standard deployment model: one Censhare Render Client per tenant, each started using a dedicated OS user.
On-premise setups are free to organize things differently. This might require aligning account naming, or adjusting OS username mapping in the tenant-id-pattern / tenant-id-replacement attributes in the XML configuration file .
If a Censhare Render Client serves multiple tenants using a single OS account, the tenant identity cannot be distinguished from the username alone: Per-job font isolation cannot be applied reliably.
The tenant directory name is derived from the OS username:
-
Apply the configured regex pattern supplied in
tenant-id-pattern -
Substitute the result by using the pattern supplied in
tenant-id-replacement.
The following examples show how this can be used:
-
Example: Identity mapping (default)
OS username = tenantA tenant-id-pattern = (.*) tenant-id-replacement = $1 → tenant directory = <font-base-directory>/tenantA -
Example: Stripping a prefix from the username:
OS username = svc_tenantA tenant-id-pattern = ^svc_(.*) tenant-id-replacement = $1 → tenant directory = <font-base-directory>/tenantA -
Example: adding a prefix to the folder name
The reverse direction also works:tenant-id-replacementmay contain literal text in addition to the capture-group reference.OS username = tenantA tenant-id-pattern = (.*) tenant-id-replacement = fonts-$1 → tenant directory = <font-base-directory>/fonts-tenantAIf
tenant-id-patternis syntactically invalid, a warning is logged and the Censhare Render Client falls back to the identity mapping ((.*)/$1).
Operating modes
Two modes exist, selected by the font-detection-threshold attribute.
Link-All mode
Applies when the tenant's font count is below the font-detection-threshold.
-
All tenant fonts are hardlinked into the
Document Fontsfolder. -
No document is opened just for font detection.
-
Faster setup
-
Best for small font pools
Detection mode
Applies when the tenant's font count is at or above the font-detection-threshold.
-
The Censhare Render Client scans the command sequence for all
OpenCommandentries, deduplicates the documents to inspect, and opens each one temporarily. -
For each document, the bundled ExtendScript
GetDocumentFonts.jsxis executed on the InDesign Server to extract the PostScript names actually used by the document. -
Detected PostScript names are aggregated across all documents, resolved against the tenant font index, and only the required fonts are linked.
-
Documents opened just for detection are closed immediately after the script result has been collected.
Choosing the threshold
The threshold defines the switch-over point between link-all and detection mode. For most deployments the default 30 works well:
-
Small pools stay in link-all mode: cheap and no detection overhead
-
Large pools automatically end up in detection mode which scales.
The threshold value only matters when a tenant's font count is close to the boundary. For pools that are clearly below or well above 30, changing it has no effect.
Font index
Per-tenant index
Each tenant directory contains its own font-index.xml. There is no global index across tenants.
Format
The index uses XML. It groups candidate font files by PostScript name and stores per-candidate metadata: family, subfamily, full name, format, SHA-256). Candidate paths are stored relative to the tenant font root.
<font-index version="5" fingerprint="...">
<font ps-name="HelveticaNeueLTStd-BdEx">
<candidate path="CAC/HelveticaNeueLTStd-BdEx.otf"
family="Helvetica Neue LT Std" subfamily="BdEx"
full-name="Helvetica Neue LT Std BdEx"
format="OTF" sha256="..."/>
<candidate path="CAM/HelveticaNeueLTStd-BdEx.otf"
family="Helvetica Neue LT Std" subfamily="BdEx"
full-name="Helvetica Neue LT Std BdEx"
format="OTF" sha256="..."/>
</font>
</font-index>
Ambiguous PostScript names
If multiple font files share the same PostScript name, all of them are kept as candidates in deterministic order. At resolution time the first candidate is selected, and a warning may be logged during index creation so the ambiguity is visible in diagnostics.
Admin action
Review such warnings and clean up the tenant pool. Duplicate PostScript names represent an ambiguous pool and should be resolved at the source.
As a more direct alternative to searching the log file, the tenant's font-index.xml can be opened in a text or XML editor: any <font> element that contains more than one <candidate> child indicates a PostScript-name collision for that entry. This can be a faster way to audit a tenant pool than log analysis, especially for administrators who are comfortable reading XML.
Staleness detection
At the start of every job the Censhare Render Client verifies the index against the current state of the tenant directory. A rebuild is triggered when any of the following conditions is true:
-
font-index.xmlis missing or corrupt. -
The stored fingerprint (relative path + size + modification time of every font file) differs from the recomputed fingerprint. The fingerprint is computed this way: relative path + size + modification time of every font file.
-
Any font file is newer than
font-index.xml.
Concurrency
A per-tenant lock serializes all index reads and rebuilds. Concurrent jobs for the same tenant either share a freshly built index or wait for the in-progress rebuild to complete.
Typical runtime
Index creation time is proportional to the font count and file sizes. The SHA-256 is computed per file. Expect a few seconds per 1,000 fonts on typical hardware.
Hardlinks, volumes, and permissions
Hardlinks
Fonts are linked into Document Fonts via java.nio.file.Files.createLink(). No copies are created. A hardlink creates a second directory entry pointing to the same inode:
-
No disk space is consumed per job.
-
All jobs for a tenant share the same physical font files.
Same-volume requirement
Hardlinks cannot span filesystem volumes. The Censhare Render Client verifies at setup time that the working directory and the tenant font directory are on the same volume.
If not:
-
A job that needs font isolation fails immediately with the error message:
Document Fonts: working directory {0} and tenant font directory {1} are on different filesystem volumes, hardlinks require both paths to be on the same volume -
Jobs that do not need font isolation are unaffected. This is the case if the feature is disabled via
enabled="false".
Admin action
Place the working directory on the same volume as the tenant font pool.
Job working directory and cleanup
-
Each job runs inside
<working-directory>/<job-uuid>/. -
InDesign documents for the job are placed inside this directory, not directly in
java.io.tmpdir. This way, InDesign finds the adjacentDocument Fontsfolder. -
After the job completes, the working directory is deleted recursively. Hardlinks are removed. The original font files in the tenant pool are not touched.
No explicit cleanup is required from the administrator during normal operation.
Logging and troubleshooting
The table below shows the English log messages related to the font isolation feature. Placeholders such as {0} / {1} are filled in at runtime with the actual tenant ID or path. Translations for other languages are available in client.properties.
|
Log message (EN) |
Severity |
Meaning |
Suggested action |
|---|---|---|---|
|
Setting up Document Fonts for tenant {0} |
Info |
Setup is running; |
None. For information only. |
|
Document Fonts: font-base-directory is not configured |
Error (job fails) |
Feature is enabled but |
Set |
|
Document Fonts: font-base-directory does not exist: {0} |
Error (job fails) |
The configured path does not exist; |
Verify the mount / path; create the directory; or set |
|
Document Fonts: tenant font directory does not exist: {0} |
Error (job fails) |
The resolved tenant directory does not exist; |
Create the tenant directory, adjust |
|
Document Fonts: working directory {0} and tenant font directory {1} are on different filesystem volumes, hardlinks require both paths to be on the same volume |
Error (job fails) |
Working directory and tenant directory are on different volumes; hardlinks impossible. |
Move the working directory to the same volume as the tenant font pool. |
|
Document Fonts: tenant font directory {0} is not writable, the font index cannot be maintained |
Error (job fails) |
The OS account under which the Censhare Render Client runs has no write permission on the tenant font directory. |
Grant write permission on the tenant's own subdirectory. |
|
Document Fonts: working directory {0} is not writable, the job working directory cannot be created |
Error (job fails) |
The OS account has no write permission on the configured |
Grant write permission on the working directory. |
Additional failure modes
|
Condition |
Severity |
Behavior |
Suggested action |
|---|---|---|---|
|
Index rebuild timeout |
Error (logged) |
Rebuild aborted and previous index is restored from backup. |
Increase |
|
Index wait timeout |
Error (job fails) |
Job cannot obtain a consistent index within the wait timeout. |
Raise |
|
Detection-mode script failure |
Error (job fails) |
Opening a document, running |
Check the InDesign Server log. Verify the affected document is intact. There is no automatic fallback to link-all mode. |
|
Ambiguous PostScript name warning |
Warning may be logged during index creation |
Multiple font files share the same PostScript name. The first candidate is used. |
Remove duplicates from the tenant font pool. |
Rollout recommendation
For the initial rollout:
-
Keep the existing global InDesign font folder connected. This preserves the previous resolution path as a fallback while per-job isolation is introduced in production.
-
Add or update the
<document-fonts>element injavarender-preferences.xmland setenabled="true"explicitly. The feature is off by default and does not activate itself on upgrade. The minimum set of attributes to configure and the full attribute reference are described, see Configuration. -
Monitor logs and rendering output.
After the new mechanism has been validated in regular operation:
-
Remove the global font folder from InDesign Server.
-
From that point on, font resolution relies entirely on the dynamically populated
Document Fontsfolder — full per-job, per-tenant isolation.
Per-Job overrides (for developers and integrators)
This section is intended for solution developers, partners, and customers who build their own render pipelines against the Censhare Render Client.
Administrators can skip the following section if they only want to configure javarender-preferences.xml.
When a custom server-side component builds the command sequence that is sent to the Censhare Render Client, two attributes on the root <cmd> element can override the global configuration for that specific job.
|
Attribute |
Type |
Effect |
|---|---|---|
|
tenant-id |
string |
Overrides the tenant directory name derived from the OS username. Useful when the server has explicit knowledge of the tenant identity for a job and should not rely on the OS account mapping. |
|
document-fonts-enabled |
boolean |
Overrides the global Allows the server to selectively enable or disable font isolation per job. |
Precedence:
-
per-job attributes
-
javarender-preferences.xml -
defaults.
All other <document-fonts> settings (thresholds, timeouts, base directory, regex) are global and cannot be overridden per job.
Example command sequence
A command sequence that applies to a specific tenant and keeps font isolation enabled for this job:
<cmd tenant-id="customer-acme" document-fonts-enabled="true">
<SetupDocumentFontsCommand/>
<OpenCommand document-ref="..."/>
<!-- further commands ... -->
</cmd>
Notes:
-
SetupDocumentFontsCommanddoes not have to be included explicitly. The Censhare Render Client auto-inserts it as the first command if it is missing. Optionally, it can be included explicitly. This is only useful in special cases, for example to reserve a specific position in the sequence. -
If
tenant-idis omitted, the Censhare Render Client derives the tenant ID from the OS username via the configured regex, exactly as documented in Tenant ID Resolution. -
If
document-fonts-enabledis omitted, the global value from<document-fonts>applies.