- Test calibre-server manually as the service user before editing systemd.
- Fix library paths, permissions, HOME settings, command options, and port conflicts.
- Use journal logs and a clean local library to isolate failures.
- Confirm the Symptom With a Small Safe Test
- Check the Library Path and calibre-server Options
- Fix Service User Permissions and Environment Differences
- Check Ports, Interfaces, Firewall, and Network Access
- Use Logs to Identify the First Real Error
- Run a Clean Temporary Test Before Reinstalling
- Apply the Corrected systemd Configuration
- Quick Fix Checklist
- Frequently Asked Questions
When a calibre-server Linux service is not starting, cannot find its library, or exits immediately, the cause is usually not the e-book files themselves. The most common failures are an incorrect library path, insufficient permissions for the service user, an invalid command option, a port conflict, or a difference between your interactive shell and the environment provided by systemd. The safest approach is to test the exact server command manually as the service user, correct the first visible error, and stop changing settings as soon as the server remains active and loads the expected library.

Start with free Canva bundles
Browse the freebies page to claim ready-to-use Canva bundles, then get 25% off your first premium bundle after you sign up.
Free to claim. Canva-ready. Instant access.
1. Confirm the Symptom With a Small Safe Test
Begin by determining whether calibre-server itself fails or only the systemd service fails. This distinction prevents unnecessary changes to the library, calibre configuration, firewall, or installation.
1.1 Check the service state
Run the following commands, replacing calibre-server.service if your unit uses another name:
sudo systemctl status calibre-server.service --no-pager -l
sudo journalctl -u calibre-server.service -b --no-pager -n 100
The status output tells you whether systemd started the process, while the journal normally contains the error written when it stopped. Look for the first specific message about a missing path, permission denial, unavailable port, invalid option, missing library, or nonexistent executable. Later messages may merely describe the consequences of that first failure.
If the service is shown as active (running), the startup problem is resolved. Test the local server address before changing anything else. If the configured port is 8080, for example, open http://127.0.0.1:8080 on the server or run:
curl -I http://127.0.0.1:8080
A successful HTTP response means the server process is listening. If remote devices still cannot connect, move to the networking checks rather than continuing to edit the service.
1.2 Find the actual calibre-server executable
Systemd services use a controlled environment and may not have the same PATH as your login shell. Find the executable used by your successful command-line installation:
command -v calibre-server
readlink -f "$(command -v calibre-server)"
calibre-server --version
Place the full executable path in ExecStart, such as /usr/bin/calibre-server or /opt/calibre/calibre-server. Do not assume the location is identical across distribution packages, calibre's official installer, containers, or manually managed installations.
Success means the executable exists, is runnable, and prints its version when invoked from a terminal. If command -v returns nothing, fix the calibre installation or locate the executable before investigating systemd.
1.3 Test the exact command manually first
Copy the executable, options, and library path from ExecStart. Run them in the foreground without adding --daemonize:
/opt/calibre/calibre-server --listen-on 127.0.0.1 --port 8080 "/srv/calibre/Library"
If the command works as your own account, repeat it as the account named by the unit's User= setting:
sudo -u calibre -H /opt/calibre/calibre-server \
--listen-on 127.0.0.1 \
--port 8080 \
"/srv/calibre/Library"
This is one of the most useful tests for a calibre-server Linux service not starting. If it fails as the service user, systemd is probably not the underlying cause. The service account cannot access a required file, directory, port, configuration location, or runtime dependency.
Leave the manual process running long enough to open its local address. Stop it with Ctrl+C before starting the systemd service. Once the command works as the intended user, use that same command in the unit.
2. Check the Library Path and calibre-server Options
2.1 Specify an absolute library path
A headless service should receive the library folder explicitly. If no library path is supplied, calibre-server may rely on libraries known to the calibre configuration associated with the current user. A dedicated service account can have a different configuration and HOME directory, so it may know nothing about the library opened in the desktop application.
Use the folder containing the library's metadata.db file:
ls -l "/srv/calibre/Library/metadata.db"
Then provide that folder, not the database file, in ExecStart:
ExecStart=/opt/calibre/calibre-server "/srv/calibre/Library"
If the path contains spaces, quote the complete path. Do not use ~, a relative path, or a shell variable unless you have deliberately arranged for it to be expanded. Systemd does not execute ExecStart through a shell by default.
Success means the server home page displays the intended library and its books. Stop changing the path when the correct collection appears.
2.2 Verify every command option
Run the installed program's help command instead of copying options from an old guide:
/opt/calibre/calibre-server --help
Check the spelling and value of each option in ExecStart. Options especially relevant to service startup include:
--listen-onfor the network interface--portfor the listening port--logfor a server log file--access-logfor HTTP access records--userdbfor the authentication database--enable-authwhen configured accounts are required--url-prefixwhen operating behind a reverse proxy under a subpath--ssl-certfileand--ssl-keyfilefor direct HTTPS
Every file passed through an option must be readable by the service user. Any directory used for a writable log, user database, PID file, upload, or library must allow the necessary access.
2.3 Keep the process in the foreground
For a normal unit with Type=simple, do not add --daemonize. Systemd expects the process launched by ExecStart to remain in the foreground. If calibre backgrounds itself, systemd may decide that the main process exited, lose track of it, or repeatedly restart the service.
A practical baseline unit is:
[Unit]
Description=calibre Content server
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=calibre
Group=calibre
WorkingDirectory=/srv/calibre
Environment=HOME=/var/lib/calibre
ExecStart=/opt/calibre/calibre-server --listen-on 0.0.0.0 --port 8080 "/srv/calibre/Library"
Restart=on-failure
[Install]
WantedBy=multi-user.target
Adjust the account, executable, interface, port, HOME directory, and library location for your system. If a reverse proxy is the only intended client, use --listen-on 127.0.0.1 instead of exposing the process on every IPv4 interface.
3. Fix Service User Permissions and Environment Differences
3.1 Inspect access as the service user
The user named in User= must be able to traverse every parent directory and read the library database, book folders, covers, and formats. If server-side changes are enabled, that user also needs appropriate write access.
sudo -u calibre -H test -r "/srv/calibre/Library/metadata.db" && echo readable
sudo -u calibre -H test -x "/srv/calibre/Library" && echo traversable
namei -l "/srv/calibre/Library/metadata.db"
The namei output is useful because a service can be denied by a parent directory even when the library folder itself appears readable. Correct ownership or group access narrowly rather than granting universal write permission.
sudo chown -R calibre:calibre "/srv/calibre/Library"
Use that command only if the dedicated service account is supposed to own the entire library. If a desktop account also manages it, a shared group and carefully selected group permissions may be more appropriate. Avoid running the server as root merely to hide a permission problem.
Success means the manual command works under sudo -u calibre -H and systemd no longer reports Permission denied.
3.2 Give the service a valid HOME directory
Services do not necessarily receive the HOME, PATH, locale, or session variables available in an interactive shell. A dedicated account may also have a nonexistent or unwritable home directory. This can affect configuration files, caches, authentication data, temporary files, and any behavior that depends on per-user calibre state.
Inspect what systemd is applying:
sudo systemctl show calibre-server.service \
-p User -p Group -p Environment -p ExecStart -p WorkingDirectory
getent passwd calibre
Create a private state directory if needed and assign it to the service account:
sudo install -d -o calibre -g calibre -m 750 /var/lib/calibre
Then set Environment=HOME=/var/lib/calibre in the unit. If you use an environment file, remember that systemd environment assignments are not ordinary shell scripts. Keep values explicit, and inspect the loaded unit afterward.
3.3 Watch for systemd security restrictions
A hardened unit may contain directives such as ProtectHome=true, ProtectSystem=strict, ReadOnlyPaths=, or InaccessiblePaths=. These can prevent calibre from seeing a library even when Unix ownership and mode bits look correct.
sudo systemctl cat calibre-server.service
sudo systemctl show calibre-server.service -p ProtectHome -p ProtectSystem
If the library is under /home and ProtectHome=true, move it to an appropriate service location or adjust the restriction deliberately. Do not disable every security control without identifying the directive responsible.
3.4 Treat network libraries carefully
Do not point a headless service at an SMB, NFS, cloud-synchronized, or other remotely mounted library without checking startup order, availability, locking behavior, and file ownership. The mount may be absent when the service starts, causing calibre to see an empty directory or fail to open metadata.db. Interrupted connections and simultaneous writers can also put the library at risk.
Confirm the expected filesystem is mounted before starting the server:
findmnt "/srv/calibre/Library"
mountpoint "/srv/calibre/Library"
For a systemd-managed mount, add an appropriate mount dependency or use RequiresMountsFor=/srv/calibre/Library. A local filesystem is generally the simpler and safer location for an actively managed calibre library. If storage must be remote, maintain tested backups and avoid having multiple calibre processes modify the same library concurrently.
4. Check Ports, Interfaces, Firewall, and Network Access
4.1 Find port conflicts
An immediate exit with an address-related error often means another process already uses the configured port:
sudo ss -ltnp | grep ':8080 '
sudo lsof -nP -iTCP:8080 -sTCP:LISTEN
Stop the unintended process or choose an unused port with --port. Also make sure an old manually launched calibre-server process is not still running.
Success means only the intended process listens on the selected address and port. Once that is true, do not keep changing ports.
4.2 Distinguish binding from firewall problems
A firewall does not usually make calibre-server exit at startup. First verify the process locally:
curl -I http://127.0.0.1:8080
sudo ss -ltnp | grep calibre
If local access works but another computer cannot connect, check --listen-on. A server bound to 127.0.0.1 accepts only local connections, which is correct behind a local reverse proxy but not for direct LAN access. For direct IPv4 access, an appropriate LAN address or 0.0.0.0 may be needed.
After confirming the bind address, permit the selected port through the host firewall using your distribution's normal firewall tool. Test from a device on the same network. Antivirus software on Linux is less commonly the cause of an immediate service exit, but endpoint security or mandatory access controls can deny file or network access and should be checked if logs show explicit denials.

5. Use Logs to Identify the First Real Error
5.1 Read systemd logs in context
Restart the service once, then inspect only the current boot's relevant messages:
sudo systemctl daemon-reload
sudo systemctl restart calibre-server.service
sudo journalctl -u calibre-server.service -b --no-pager -n 200
For a live view:
sudo journalctl -fu calibre-server.service
Common patterns include:
- No such file or directory: Check the executable, library, user database, certificate, key, log path, or working directory.
- Permission denied: Test directory traversal and file access as the configured service user.
- Address already in use: Find the process occupying the port.
- Unknown option: Compare
ExecStartwith the installed command's--helpoutput. - Failed to determine user credentials: Confirm that the account and group in the unit exist.
- Start request repeated too quickly: Read earlier journal entries to find the original crash rather than increasing restart limits.
5.2 Add a dedicated server log only when useful
By default, server information and errors can be written to standard output and captured by the journal. If you prefer a separate log, supply a writable absolute path:
ExecStart=/opt/calibre/calibre-server \
--log /var/log/calibre/server.log \
--access-log /var/log/calibre/access.log \
--port 8080 "/srv/calibre/Library"
Create the directory with suitable ownership before starting the service. The access log is mainly useful after startup because it records client requests. A completely empty access log does not explain an early process failure.
5.3 Use calibre-debug selectively
calibre-debug --paths can display paths used to establish the calibre environment, which may help when a command works in one installation context but not another:
sudo -u calibre -H /opt/calibre/calibre-debug --paths
For this service symptom, however, the foreground calibre-server output and systemd journal are normally more direct than GUI debug modes, device-detection debugging, conversion output, or editor logs. Those tools address different calibre features and should not distract from a headless server startup failure.
6. Run a Clean Temporary Test Before Reinstalling
Before deleting the library, reinstalling calibre, or changing many service settings, create a minimal local test library. This separates installation and service problems from issues involving the real library's path, mount, permissions, or database.
- Create an empty local directory owned by the service account.
- Run calibre-server manually as that account with a different unused port.
- Open the local address.
- If it works, return to the real library and investigate its path, permissions, filesystem, or database access.
sudo install -d -o calibre -g calibre -m 750 /var/lib/calibre/test-library
sudo -u calibre -H /opt/calibre/calibre-server \
--listen-on 127.0.0.1 \
--port 18080 \
/var/lib/calibre/test-library
If this minimal command remains running and answers at http://127.0.0.1:18080, the executable and basic runtime are functional. Do not reinstall calibre. Compare the clean path with the real library setup one difference at a time.
If even the clean local test fails, capture its complete terminal output. Verify the executable and required runtime libraries, then review how calibre was installed. Reinstallation is reasonable only after the same binary fails with a local writable directory and a free port.
7. Apply the Corrected systemd Configuration
After editing the unit, reload systemd and restart the service:
sudo systemctl daemon-reload
sudo systemctl restart calibre-server.service
sudo systemctl status calibre-server.service --no-pager -l
Enable startup at boot only after the service works reliably:
sudo systemctl enable calibre-server.service
Verify all three success conditions:
- The unit remains
active (running)instead of repeatedly restarting. - The selected port is listening on the intended interface.
- The browser displays the correct library and expected books.
Once these conditions are met, stop changing permissions, environment variables, ports, and command options. Additional changes can introduce a new fault into a working configuration.
8. Quick Fix Checklist
- Read
systemctl statusand the current boot's journal entries. - Use the absolute path to the
calibre-serverexecutable. - Use an absolute path to the folder containing
metadata.db. - Quote library paths containing spaces.
- Run the exact command manually as the service user.
- Confirm that account can traverse every parent directory.
- Set a valid writable HOME directory when using a dedicated account.
- Check each option against
calibre-server --help. - Do not combine
Type=simplewith--daemonize. - Check whether another process is using the configured port.
- Verify the bind address before changing firewall rules.
- Ensure network storage is mounted before the service starts.
- Test with a clean local directory before reinstalling or deleting anything.
- Stop troubleshooting when the service stays active and the correct library loads.
9. Frequently Asked Questions
9.1 Why does calibre-server work in my terminal but fail as a service?
Your terminal and systemd can use different users, groups, HOME directories, working directories, PATH values, permissions, and environment variables. Run the command with sudo -u SERVICEUSER -H to reproduce the service account's access conditions, then use absolute paths in the unit.
9.2 Why does the service start but show the wrong library?
The service may be running under an account with different saved calibre settings. Pass the intended library folder explicitly to calibre-server. It should be the directory containing metadata.db, not the database file itself.
9.3 What causes calibre-server to exit immediately?
Typical causes include a nonexistent executable, inaccessible library, invalid option, occupied port, unreadable user database or certificate, unwritable log destination, missing runtime dependency, or use of --daemonize with an unsuitable systemd unit type. The first journal error usually identifies the category.
9.4 Should I run the service as root?
No. Use a dedicated account or the account that appropriately owns the library. Running as root increases risk and conceals permissions that will remain incorrect for a safer configuration.
9.5 Can calibre-server use a library on a NAS?
It may work, but remote filesystems require care. The mount must exist before startup, the service user must receive the correct ownership mapping, and the storage must behave reliably with the library database and files. Avoid simultaneous writers, keep backups, and prefer a local active library when possible.
9.6 Do I need to reinstall calibre when the service cannot start?
Usually not. First run the installed executable manually as the service user with a clean local test directory and unused port. If that succeeds, the installation is functional and the fault is in the real service configuration, library location, permissions, environment, or network storage.