calibre-server Linux Service Not Starting: How to Fix It

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.

Linux server administrator diagnosing a failed e-book service with terminal checks and a library folder.

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-on for the network interface
  • --port for the listening port
  • --log for a server log file
  • --access-log for HTTP access records
  • --userdb for the authentication database
  • --enable-auth when configured accounts are required
  • --url-prefix when operating behind a reverse proxy under a subpath
  • --ssl-certfile and --ssl-keyfile for 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.

Service log entries narrowing from repeated warnings to one underlying startup error.

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 ExecStart with the installed command's --help output.
  • 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.

  1. Create an empty local directory owned by the service account.
  2. Run calibre-server manually as that account with a different unused port.
  3. Open the local address.
  4. 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 status and the current boot's journal entries.
  • Use the absolute path to the calibre-server executable.
  • 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=simple with --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.


Citations

  1. Official instructions for running the standalone Content server and creating a systemd service. (calibre Content Server Manual)
  2. Official reference for calibre-server syntax, library arguments, networking, authentication, and logging options. (calibre-server Command Reference)
  3. Official reference for calibre debugging commands and environment path output. (calibre-debug Command Reference)
  4. Reference documentation for reading and filtering logs from the systemd journal. (systemd journalctl Manual)
  5. Linux manual documentation covering systemd service users, working directories, HOME, environment variables, and filesystem restrictions. (systemd.exec Manual)
Cindy, ContentBASE creator assistant

MEET CINDY

Your ContentBASE creator assistant

Cindy helps creators find Canva templates, content ideas, and simple ways to make better social media posts faster.

Want ready-to-use templates? Claim the free Canva bundles or browse the full bundle store.