Skip to content
streamneo.
Setup Guides12 min read

How to Configure systemd to Restart a Failed FFmpeg YouTube Stream

Configure a systemd service for FFmpeg, inspect restart behaviour and logs, and understand the limits of automatic recovery.

sn.
StreamNeoPublished 5 October 2026
Worth sharing?

To have systemd restart FFmpeg after the process exits unsuccessfully, run FFmpeg as the service’s foreground process and set Restart=on-failure with a deliberate RestartSec= delay. This can recover from some process failures, but it cannot fix the cause of a failure or detect every stalled stream.

The example below gives you a service unit, commands to install and inspect it, and a way to distinguish systemd’s process supervision from FFmpeg’s output recovery. Treat the example values as a starting policy: paths, inputs, account permissions and restart limits need to match your machine.

Choose a service user and FFmpeg command

A system service needs an account and an executable command. Run FFmpeg as an unprivileged user with access to the media, configuration and directories it actually needs. The example uses an account named stream and a working directory at /srv/stream; create or substitute those before enabling the service. Do not run a long-lived encoder as root merely to avoid sorting out file permissions.

Check the executable path on your system with command -v ffmpeg. The unit below uses /usr/bin/ffmpeg, but package installation methods can place the binary elsewhere. Likewise, make sure the input path is readable by the service user. A file that plays when you test it from your personal account may still fail under a different service account.

The sample command is for a prerecorded file intended to loop. -re reads the file at its native pace, and -stream_loop -1 repeats that file indefinitely. Neither is a universal live-input setting. For a camera, capture device, playlist or other source, use the appropriate input arguments; do not leave -stream_loop -1 in place unless looping a file is what you intend.

The output uses YouTube’s RTMP ingest address as an example. Replace the placeholder with the stream key for your broadcast, and do not paste a real key into a public repository, support ticket or shared log. A systemd unit readable by other local users can expose secrets, so consider a restricted environment file or another secret-handling method suitable for your deployment. Set its ownership and permissions so only the necessary account and administrators can read it.

Before making it a service, run the command interactively with a test stream or private event. YouTube’s encoder settings and stream health guidance explains why encoder configuration and a connection that can sustain it matter. If your main problem is that a workstation sleeps or the broadcast depends on an open desktop session, compare that setup with the practical considerations in keeping a devotional stream live without a PC. That is a different operational question from making FFmpeg restart after a process exit.

Create the systemd service unit

Create /etc/systemd/system/ffmpeg-youtube.service with an editor running as an administrator, for example sudo nano /etc/systemd/system/ffmpeg-youtube.service. Put the following in the file, then adapt the account, paths, encoding options and key before starting it:

[Unit]
Description=FFmpeg YouTube live stream
Wants=network-online.target
After=network-online.target

# Example guard against a rapid restart loop. Tune for the deployment.
StartLimitIntervalSec=300
StartLimitBurst=5

[Service]
Type=simple
User=stream
WorkingDirectory=/srv/stream
ExecStart=/usr/bin/ffmpeg -hide_banner -re -stream_loop -1 -i /srv/stream/input.mp4 -c:v libx264 -c:a aac -f flv rtmp://a.rtmp.youtube.com/live2/REPLACE_WITH_STREAM_KEY
Restart=on-failure
RestartSec=10s

[Install]
WantedBy=multi-user.target

Type=simple means systemd treats the command started by ExecStart= as the service process. Keep FFmpeg in the foreground: do not add shell backgrounding such as &, and do not have a wrapper return immediately while FFmpeg continues detached. systemd needs to observe the encoder’s process and exit status to apply its restart policy.

Wants= and After= ask for the network-online target and order this service after it. They do not guarantee that YouTube is reachable, that DNS has resolved successfully, or that the connection remains healthy after startup. Those are separate conditions to check if the service repeatedly exits or the stream stops receiving useful media.

The service account needs read access to the input and write access only where the command needs to write. If you add a local log, playlist, capture device or configuration file, check those permissions too. A useful first test is to run the exact command as the service user, with the same paths, rather than concluding that a successful run as your login account proves the unit is ready.

If you already use OBS rather than a direct FFmpeg command, the service pattern is not a drop-in replacement for OBS configuration. See what to check when OBS stops a 24/7 stream for a different failure path. The relevant point here is to supervise the actual foreground process whose exit you want systemd to detect.

Set Restart and RestartSec

Restart=on-failure tells systemd to try starting the service again after an unsuccessful exit or abnormal termination. systemd’s service unit documentation describes the restart options and the conditions that trigger them. For a streaming process, this is generally more appropriate than restarting after a clean exit: an FFmpeg command that finishes normally may have completed because the input ended or the command was stopped deliberately.

RestartSec=10s sets the delay before a restart attempt in this example. A pause prevents an immediate retry loop and gives you a moment to inspect logs or allow a transient condition to clear. The chosen delay is an operator setting, not a guarantee that a network or ingest issue will recover within that interval. Adjust it in light of the failure mode and your tolerance for an interruption.

There is a trade-off. A short delay can bring the process back sooner after a one-off exit, but repeated failures can cause repeated connection attempts without resolving anything. A longer delay reduces rapid cycling, but leaves a longer gap before a retry. Neither choice makes an invalid stream key, unreadable input, incompatible options or persistent connection fault disappear.

Use the Restart= value to express what should count as recoverable. on-failure is useful when a non-zero exit or abnormal stop should prompt a retry, while a clean stop can remain stopped. If you deliberately stop the service with systemctl, systemd does not treat that administrative stop as an instruction to keep bringing it back. When testing, distinguish an intentional stop from a failure rather than assuming every stop should restart.

Install and start the service

After saving or changing a unit file, tell systemd to reload its unit definitions. Then enable the service for later boots and start it now:

sudo systemctl daemon-reload
sudo systemctl enable --now ffmpeg-youtube.service

enable --now combines enabling at boot with starting in the current session. If you only want to test a unit before arranging for it to start at boot, use sudo systemctl start ffmpeg-youtube.service instead. To apply a change after the service is already running, reload the unit definitions and restart the service:

sudo systemctl daemon-reload
sudo systemctl restart ffmpeg-youtube.service

A successful systemctl command tells you that systemd accepted the operation, not that YouTube is receiving a healthy stream. Verify the process and check the broadcast in YouTube Live Control Room. YouTube advises testing before a live event and monitoring stream health during it. If your workflow is based on a sequence of prerecorded videos rather than one repeated file, first make sure the command has the intended input order; this FFmpeg text-file playlist guide covers that separate preparation step.

If startup fails immediately, do not keep editing restart delays as a substitute for checking the command. Verify the binary path, input file, account and file permissions, output URL and stream key. The logs usually point to the first actionable error. Correct the cause before trying again, especially if the service has already reached its rate limit.

Inspect status and logs

Start with the status output:

systemctl status ffmpeg-youtube.service

It shows whether the unit is active, failed or waiting, and gives a recent log excerpt and process result. Look for the current state and the last exit status, then read the message rather than treating “failed” as a diagnosis. A unit can be active while the stream itself is not useful, so status is one part of the check, not a full health monitor.

For a live view of new messages, use:

journalctl -u ffmpeg-youtube.service -f

To inspect recent messages without following them, use journalctl -u ffmpeg-youtube.service --since today. FFmpeg writes diagnostic output to its standard error, which systemd normally captures in the journal for a service like this. You can therefore see both FFmpeg’s explanation and systemd’s decisions to restart or stop trying.

Read the first relevant error before the sequence of later retries. A missing input file, permission denial, misspelled option, authentication problem or connection failure can cause each new process to hit the same condition. Confirm which account owns the service, whether the paths are correct from that account’s perspective, and whether the output target and credentials are current.

If your broadcast should be active but systemd says the process is running, check YouTube’s stream health as well as FFmpeg’s output. A process that remains alive is not necessarily sending useful media. The distinction matters for any always-on format, from a local news loop to a bhajan channel: a green process state does not establish that viewers can see a healthy picture and hear audio.

Understand restart limits and reset-failed

A restart policy does not mean systemd will start a service forever. systemd limits how often a unit may start within a configured interval; if it fails repeatedly, the start-rate limit can prevent further automatic starts. The unit’s StartLimitIntervalSec=300 and StartLimitBurst=5 are example guard values, not universal recommendations. They express one possible policy: permit a bounded number of starts in an interval, then stop retrying until an operator investigates.

A limit helps prevent a broken command from cycling rapidly and filling logs with repeats. The right values depend on how quickly the failure occurs and how you want to balance recovery attempts against the need for human attention. Do not copy example values as if they were a reliability guarantee. systemd’s service documentation explains that restart behaviour is subject to start-rate limiting; consult the documentation for the systemd version on your machine if you change unit-level controls.

When the service has entered a failed or rate-limited state, inspect the status and journal first. Correct the underlying problem, then clear the recorded failure state and counters:

sudo systemctl reset-failed ffmpeg-youtube.service
sudo systemctl start ffmpeg-youtube.service

The systemctl documentation describes reset-failed; it clears the failed state and resets relevant restart and start-rate-limit counters. It does not repair the cause, validate your stream key or prove that the output is healthy. If you reset without correcting the fault, the service may fail again and reach its limit again.

Use the sequence deliberately: inspect, identify and correct, reset, then start and observe. If the journal shows a persistent network or ingest problem, investigate that rather than repeatedly clearing counters. If a service was rate-limited during a planned maintenance test, record what happened so the next operator can distinguish that event from an unexpected outage.

Compare service restarts with FFmpeg recovery

There are two different recovery layers. systemd supervises the FFmpeg process: if that process exits in a way covered by the restart policy, systemd can launch a fresh process after the configured delay. FFmpeg output recovery works inside the running encoder and may handle some network-output problems without ending the process. Which output-side options apply depends on the muxer and configuration.

FFmpeg documents recovery options for network output, including features associated with its FIFO muxer, in the FFmpeg documentation. Do not add flags copied from an unrelated command without checking that documentation for your installed FFmpeg version and chosen output format. A recovery setting that applies to one muxer or output path may not apply to your RTMP setup as written.

What happens What systemd can do What to inspect
FFmpeg exits unsuccessfully Restart the process if the policy and rate limit allow Exit status, FFmpeg error and repeated cause
FFmpeg remains alive but output has a recoverable error It may do nothing, because the process has not exited FFmpeg output and applicable muxer recovery behaviour
FFmpeg remains alive but YouTube receives no useful stream It may still report the unit as active YouTube stream health, encoder settings and ingest connection
The same startup fault repeats Attempts may eventually be rate-limited Input, permissions, options, credentials and connectivity

A process restart is useful when a cleanly understood failure ends FFmpeg and a new process has a reasonable chance of succeeding. It is not a general-purpose stream watchdog. If FFmpeg hangs without exiting, systemd may see a live process; if the encoder sends poor-quality or unsustainable output, a restart repeats the same settings. YouTube’s guidance to test the configuration and monitor stream health is still important, because a process manager cannot make an unsuitable bitrate or an ingest-side issue correct.

When diagnosing, ask first whether FFmpeg exited, stayed running with output errors, or stayed running while the platform reports a stream problem. Use systemd for process supervision, FFmpeg’s documented output mechanisms where they fit, and YouTube’s health information for the receiving side. These approaches can complement one another, but none is a promise of endless restarts or a repair for the underlying fault.

For a service unit that is too much operational work for a file-based broadcast, there is also a different workflow: StreamNeo turns an uploaded video into a YouTube live stream that can keep running without leaving your own computer switched on. That removes the need to keep this particular FFmpeg process running on your machine, but it does not change the need to prepare your file and channel correctly.

Before committing, compare the operating options on the pricing page. When the file and channel are ready, start free — 24-hour trial, no card.

FAQ

Will systemd restart FFmpeg after every stop?

No. Restart=on-failure is for failures and abnormal exits, not every clean stop or deliberate administrative stop. The restart must also be permitted by the unit’s start-rate limits.

Does RestartSec=10s fix a stream that has stopped reaching YouTube?

No. It sets a delay before a restart attempt after a qualifying process exit. If FFmpeg is still running, or the stream key, encoding settings or ingest connection is wrong, the delay does not correct that issue.

What should I do after systemd says the service is start-limit hit?

Read the status and journal, then fix the cause before clearing the recorded state. systemctl reset-failed ffmpeg-youtube.service resets the failed state and counters; start the unit again only after you have checked the command and its dependencies.

Should I use systemd or FFmpeg output recovery?

They address different cases. systemd can restart FFmpeg after a qualifying process exit, while FFmpeg’s output recovery options may help with supported errors inside the output path; check the installed version and muxer documentation before relying on a specific option.

YOU’VE REACHED THE END

Keep the ideas coming.

More guides, useful tools and a little help for your next broadcast.

Back to the journal ↗
YOUR NEXT READ

A little more to explore.

More Setup Guides guides ↗ · All topics ↗