How to Enable or Disable a Service at Boot on Fedora

Use `systemctl enable` to start a service automatically at boot and `systemctl disable` to prevent it from starting, while `start` and `stop` manage the current session.

You enabled a service but it never starts after a reboot

You just installed a database or a web server on Fedora. You ran the install command, typed sudo systemctl enable postgresql, and walked away. The next morning you reboot the machine and the service is dead. Or worse, you disabled a background daemon to save RAM, but it keeps coming back after every package update. The confusion usually comes from mixing up what runs right now with what runs after a reboot. systemd separates those two concerns completely.

What systemd actually does with enable and disable

systemd does not start services by reading a flat configuration file. It builds a dependency tree and uses symbolic links to decide what boots. When you run enable, systemd copies a symbolic link from the package directory into /etc/systemd/system/. That directory is where your local overrides live. The package manager owns /usr/lib/systemd/. You own /etc/systemd/system/. The symlink tells the init system to pull the service into the boot sequence. disable removes that symlink. start and stop only affect the current runtime. They leave the boot configuration untouched. This separation prevents a temporary restart from accidentally breaking your next reboot.

The boot process targets specific milestones called targets. multi-user.target is the standard non-graphical boot state. graphical.target pulls in multi-user.target and adds display managers and desktop environments. When you enable a service, you are usually telling systemd to start it as a dependency of one of those targets. The unit file contains an After= and Wants= or Requires= directive. systemd reads those directives, resolves the order, and starts the service only after its dependencies are ready. If a dependency fails, the service stays inactive. That is why checking the dependency tree matters before you blame the service itself.

The commands you need

Here is how to control boot behavior without guessing.

# Enable the service for future boots. Does not start it now.
sudo systemctl enable httpd
# Start the service immediately in the current session.
sudo systemctl start httpd
# Combine both actions. Enables for boot and starts right now.
sudo systemctl enable --now httpd

The --now flag is the standard Fedora pattern for new installations. It saves a second and prevents the common mistake of enabling a service but forgetting to launch it. If you need to stop a service immediately while keeping it enabled for the next reboot, run sudo systemctl stop httpd. The boot symlink stays in place.

Custom unit files require an extra step. Place your .service file in /etc/systemd/system/. Never put custom units in /usr/lib/systemd/. Package updates will overwrite files in /usr/lib/. After you drop a new file into /etc/, systemd does not know it exists until you reload the manager.

# Tell systemd to rescan the unit directories.
sudo systemctl daemon-reload
# Enable and start the custom service.
sudo systemctl enable --now my-custom-app.service

Reload the daemon every time you create, move, or edit a unit file. The manager caches unit metadata in memory. Skipping the reload leaves you debugging a ghost configuration.

Verify the state before you reboot

Do not assume the symlink exists. Check the persistent state and the runtime state separately.

# Returns enabled, disabled, static, or masked.
systemctl is-enabled httpd
# Shows active state, recent logs, and dependency status.
systemctl status httpd

systemctl status is your first stop. It prints the active state, the sub-state, and the last ten log lines. If the service is active (running), the process is alive. If it shows inactive (dead) but is-enabled returns enabled, the service simply has not been started in this session yet. That is normal. If is-enabled returns masked, systemd refuses to start the unit under any circumstances. Masking creates a symlink to /dev/null. You need sudo systemctl unmask httpd before you can enable it again.

The is-enabled command returns four main values. enabled means the symlink exists and the service will boot. disabled means no symlink exists. static means the unit has no install section and can only be started as a dependency of another service. indirect means the service is enabled through a template or alias. Read the exact string. It tells you exactly how systemd will treat the unit.

Run systemctl status before you restart. Half the time the error is already in the output.

When things break and what the logs say

Services fail for three reasons: missing dependencies, permission denials, or blocked network ports. Fedora handles these differently than older init systems.

SELinux enforces mandatory access controls by default. A service that reads outside its allowed domain will be blocked instantly. The kernel drops the connection and writes a denial to the audit log. You will see a one-line summary in the journal.

audit: type=1400 audit(1698765432.123:45): avc:  denied  { name_bind } for  pid=1234 comm="nginx" src=8080 scontext=system_u:system_r:unconfined_t:s0 tcontext=system_u:object_r:unreserved_port_t:s0 tclass=tcp_socket

Do not disable SELinux to fix a service. Read the denial. The setroubleshoot package translates these lines into plain English. Run journalctl -t setroubleshoot to see the recommended fix. Most of the time you need to restore file contexts with restorecon -Rv /path/to/data or install a missing policy module.

Firewall rules are independent of systemd. Enabling a web server does not open port 80. The firewalld service manages the netfilter rules. If you skip this step, the service runs perfectly but external clients get a connection refused.

# Add the HTTP service to the persistent firewall configuration.
sudo firewall-cmd --permanent --add-service=http
# Apply the change to the running firewall without dropping connections.
sudo firewall-cmd --reload

Always reload the firewall after a rule change. The runtime configuration and the persistent configuration diverge if you skip this step.

Package naming also catches people off guard. Fedora uses httpd for Apache. Debian uses apache2. Fedora uses postgresql for the database cluster. The unit name usually matches the package name. If systemctl enable complains that the unit file not found, verify the package is installed with rpm -q httpd. Install it with sudo dnf install httpd before touching systemd.

Check the journal before you guess. journalctl -xeu httpd filters the logs to that specific unit and adds explanatory context.

Which command fits your situation

Use systemctl enable when you want the service to survive a reboot but do not need it running right now. Use systemctl enable --now when you are setting up a fresh server and need the service live immediately. Use systemctl start when you are testing a configuration change and want to avoid a full reboot. Use systemctl disable when you want to stop the service from starting automatically while keeping the package installed. Use systemctl mask when you want to prevent any user or dependency from starting the service, even accidentally. Use systemctl daemon-reload when you have added, removed, or edited a unit file in /etc/systemd/system/.

Where to go next