If FFmpeg exits on an Ubuntu host, you can have systemd start it again by running the encoder as a service and choosing a restart policy. That recovers an exited process; it does not show that YouTube is receiving healthy video, so you must check the service and the broadcast separately.
The pattern below gives you a practical starting point, not a universal unit file. Your FFmpeg command, installed systemd version, stream key handling and failure mode all matter. Test the service with your own stream and inspect what happens after both an intentional stop and a genuine encoder failure.
Confirm the exit and read the useful logs
Before changing configuration, establish what failed. A restart policy helps only when systemd can see that the main process has exited. If FFmpeg is still running but stalled, or if it continues sending a broken output, a service configured to restart on exit may do nothing.
If FFmpeg is currently started in a terminal, note the final output and its exit status before closing the session. If it is already managed by systemd, inspect its state and recent journal entries. Replace ffmpeg-stream.service with your actual unit name:
sudo systemctl status ffmpeg-stream.service
sudo journalctl -u ffmpeg-stream.service -n 100 --no-pager
The status output can show whether the service is active, failed or restarting. The journal gives you the process output captured by systemd, including errors near the end of an attempt. Look for the first meaningful failure, rather than assuming the last line is the cause. A missing input file, invalid option, permission problem or rejected connection can each produce a different sequence of messages.
If the unit has restarted several times, read back through the earlier attempts. Repeated messages can obscure the first event that started the cycle. Make a note of the time and error, then check whether the same problem recurs after each launch. Restarting a command with a bad path or invalid credentials will reproduce that error; it will not repair it.
You can also inspect FFmpeg’s own diagnostic output when testing the command manually. Run it in the foreground so errors remain visible, and avoid putting a stream key into a public script or shell history. If you need a broader explanation of connection drops, the guide to a YouTube stream disconnecting covers another common class of failure, though its OBS-specific cause is different from a crashed FFmpeg process.
Put the command under systemd
A system service is useful because systemd tracks the foreground process and can act when that process exits. It also gives you a consistent place to view state and logs after you disconnect from SSH. Do not background FFmpeg inside the service with &, or use a wrapper that returns immediately while leaving an untracked process behind. The command should remain the service’s main process.
Create a unit file, for example at /etc/systemd/system/ffmpeg-stream.service:
[Unit]
Description=FFmpeg YouTube live stream
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=streamer
WorkingDirectory=/home/streamer/live
ExecStart=/usr/bin/ffmpeg -re -stream_loop -1 -i /home/streamer/live/program.mp4 -c:v libx264 -c:a aac -f flv rtmp://a.rtmp.youtube.com/live2/REPLACE_WITH_STREAM_KEY
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
This is a shape to adapt, not a verified command for your host. Confirm FFmpeg’s path with command -v ffmpeg, use the actual media file and encoding options for your case, and test the command outside the unit first. The sample’s input is a looping file; a playlist, live input or different output format needs a different command. Keep ExecStart on one line in the unit file.
The User should be an account that can read the media and execute FFmpeg without unnecessary privileges. Check ownership and permissions on the working directory and input file. A unit that works as your login user may fail as the service account simply because that account cannot read a file in your home directory.
Treat the destination and stream key as sensitive. A unit file is not automatically private merely because it sits under /etc. Restrict access appropriately, consider a supported credentials mechanism for your installed systemd version, and do not paste a real key into screenshots, issue trackers or public repositories. If you need to rotate a key, update the service configuration and confirm the encoder uses the current value in YouTube Live Control Room.
A service can also be made dependent on network readiness, as in the example, but that does not guarantee that an internet route or YouTube ingest endpoint is actually reachable. It only expresses an ordering relationship with the host’s network-online target, whose behaviour depends on the system’s network configuration. The first run and its logs are still necessary checks.
If you are building a recurring video schedule rather than a single looping file, separate playlist switching from crash recovery. The cron and FFmpeg playlist guide concerns scheduled changes; systemd’s job here is to supervise the process that runs the current command.
Choose a restart rule and delay
Restart= controls which exits lead systemd to try again. The suitable value depends on whether a normal FFmpeg exit should be treated as a fault. For a long-running channel, you may intend the process to stay alive until an operator stops it; in another workflow, a clean exit may mean the job is finished and should remain stopped. Read the service documentation installed on your Ubuntu host for the exact semantics and any applicable start-rate limits.
An FFmpeg-user mailing-list report describes one working configuration using Restart=always and RestartSec=5. That is an individual case, not a default for every channel. A five-second delay may be too short if a persistent problem causes rapid retries, while a long delay means viewers may see a longer interruption before the next attempt. Choose deliberately, then observe the journal under a controlled test. The mailing-list example provides context for those settings, but your host and command may behave differently.
The sample unit uses Restart=on-failure and RestartSec=10 to illustrate a conservative starting shape, not a recommendation that fits every deployment. Some operators may choose always so that a clean process exit also leads to another run. That can be useful for a command expected to run continuously, but it also means an intentional stop needs to be handled with systemd’s controls and the unit’s documented behaviour in mind. Do not rely on a setting without checking how it interacts with your installed version and how you intend to stop the stream.
A delay prevents a retry from happening immediately, but it is not a complete retry strategy. systemd applies start-rate limiting, and repeated failures may eventually stop further starts until the issue is addressed or the unit is reset. Exact details depend on the systemd version and configuration. If logs show that starts are being limited, use the locally installed documentation and journal messages to understand the limit instead of increasing retry frequency blindly.
A restart policy is also not a health check. It generally reacts to process lifecycle events, not to the quality of the picture, audio or remote ingest. If FFmpeg remains alive while output has stopped, or if YouTube shows an error while the process is still running, a simple restart-on-exit service may not detect the problem. Build a separate monitoring approach only if you can define a reliable signal of progress and a sensible response to a false alarm.
Reload the unit and start it
Once the file is saved, ask systemd to reload unit definitions. Then enable the service for future boots and start it now:
sudo systemctl daemon-reload
sudo systemctl enable --now ffmpeg-stream.service
enable arranges for the unit to be started through the configured boot target; --now starts it immediately as well. If you only want to test a service without enabling it at boot, start it without enable, then decide whether it should be enabled after you have checked the result.
If systemd reports a syntax problem, inspect the exact unit file for misspelled section names, malformed directives or a command split across lines. Check the journal rather than repeatedly running the same start command. If the service starts and exits immediately, the status and journal are more useful than changing the restart delay first: find whether FFmpeg rejected an option, could not access its input, or failed to connect.
After edits, reload systemd again. A changed unit file is not necessarily reflected in the running service until you reload the definitions and restart or otherwise start the unit. Keep a copy of the previous working command and configuration while testing, so you can distinguish a systemd change from a change in FFmpeg arguments.
Check service state and journal output
Use status to see the current state, and the journal to inspect the latest output:
sudo systemctl status ffmpeg-stream.service
sudo journalctl -u ffmpeg-stream.service -f
The first command is a snapshot; the second follows new log entries. You should see whether systemd launched the process, whether FFmpeg printed an error and whether a restart followed. A service that shows as active means systemd considers its main process to be running. It is not a statement that the stream is visible to viewers or that YouTube has accepted a healthy video feed.
Test recovery in a controlled way before trusting the configuration overnight. For example, stop the service intentionally and observe the result, then start it again. If you simulate a crash, do so when an interruption is acceptable and record what the journal says. Avoid killing random FFmpeg processes on a shared host: you may affect a different job, and a restart policy might create a second attempt while you are still diagnosing the first.
Check that only one intended encoder process is running for this channel. If you manually launch FFmpeg while the service is active, you can create duplicate broadcasters competing to use the same stream key. Prefer systemctl stop and systemctl start to manage the service, and confirm the old process is gone before launching a manual test.
If repeated start attempts stop, do not increase the rate limit as the first response. Fix the underlying error, check whether the media path or credentials changed, and review the relevant systemd documentation for the installed version. A persistent bad command can otherwise produce a cycle of failed attempts and confusing logs. Record a known-good command, the time of the last successful start and the first error after failure; those details make remote troubleshooting much more practical.
Know what systemd can and cannot recover
There are different failure shapes, and they call for different checks. A service manager can relaunch an exited process. FFmpeg’s own output handling can sometimes recover from temporary output failures while the process remains alive. A watchdog can look for a signal that a process has stalled, but it needs a meaningful measure of progress and carefully chosen response behaviour.
| Approach | Failure it may address | Boundary to remember |
|---|---|---|
| systemd restart policy | FFmpeg exits or fails in a way covered by the selected policy | Does not itself prove that a running process is sending healthy video to YouTube |
| FFmpeg FIFO muxer recovery | Some temporary output failures while FFmpeg continues processing | In-process recovery; it does not relaunch FFmpeg after a process crash |
| Progress watchdog | A process appears alive but is not making expected progress | Needs a reliable signal and thresholds; a watchdog can miss failures or react incorrectly |
The FFmpeg documentation for the FIFO muxer describes recovery behaviour for temporary output failures. That is a different layer from systemd restarting an exited process. Whether it belongs in your command depends on the output path and failure mode; do not add it as a substitute for checking the resulting stream.
A watchdog is a further layer, not a reason to assume every silent failure is detectable. A process can make progress locally while the remote service has a problem, and a test that only checks whether the PID exists is not a stream health check. If you build one, define the signal first, decide how long a stall must persist, log every action and ensure an automated restart will not create a retry loop. For some small channels, checking the journal and Live Control Room after an alert is safer than adding an untested watchdog.
This distinction is important if you are deciding whether to keep an Ubuntu machine running for a recorded programme or move the workload elsewhere. A self-managed host offers direct control over FFmpeg and systemd, but you remain responsible for the machine, network and monitoring. A cloud workflow changes where you handle those concerns. The comparison of cloud YouTube loop services by storage retention is useful when the operational burden of managing a host becomes the decision, rather than when you are fixing this particular unit.
Verify the broadcast in YouTube Live Control Room
Once the service is active, open YouTube Live Control Room and confirm the broadcast itself. Check the stream status, preview and any encoder warnings or error messages. A successful systemd restart tells you that a process was started; the Control Room is where you check whether YouTube is receiving the expected feed and how the stream appears at the platform end.
If YouTube reports an encoder startup problem, follow its current troubleshooting guidance. The YouTube live-stream troubleshooting page advises checking the stream key and encoder configuration when relevant. Make sure the key in your service is the one for the intended broadcast and that you have not copied an old value. Treat a key as a credential: do not publish it while asking for help.
When the error points to connectivity, check the Ubuntu host’s network and consult your internet service provider if the connection issue is with the service they provide. YouTube’s troubleshooting guidance also directs users to their ISP when a connection problem is found. A local process can be running normally while the uplink is unavailable or unstable, so combine the platform status with host-side logs rather than treating either one as conclusive on its own.
After a restart, confirm that the video and audio are actually the intended programme. A control room indicator can tell you about ingest, but you still need to look at the preview or a viewer-facing playback path to catch a wrong file, silence, frozen frames or an unintended scene. If your channel uses captions or recorded lessons, verify those too; the caption guide for recorded lessons on a 24/7 stream covers a separate part of viewer-facing quality.
Write down a short recovery record: when FFmpeg exited, what the first relevant log entry said, when systemd started the next attempt, and what YouTube showed afterwards. This makes the next incident easier to diagnose. If the process restarts but the Control Room continues to show an error, investigate the input, stream key, encoder settings and connectivity instead of repeatedly adjusting the restart interval.
If managing a host, its service unit and follow-up checks no longer fits your channel’s routine, StreamNeo can remove the need to keep your own computer running by turning an uploaded video into a YouTube live stream that is monitored and restarted if it drops. That addresses a different operational burden from repairing an Ubuntu FFmpeg service, and it remains YouTube-only.
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
Does Restart=always mean my YouTube stream will never go offline?
No. It can tell systemd to start the service again after an exit, subject to the unit’s behaviour and systemd’s limits. It cannot guarantee that YouTube is receiving healthy video, that the network is available or that the process will not fail again.
Should I use RestartSec=5?
Five seconds appears in an individual FFmpeg-user example, but it is not right for every host or failure. A short delay can lead to repeated attempts against a persistent fault; choose a delay that suits the failure you expect and check your installed systemd documentation and logs.
What if FFmpeg is still running but the stream is frozen?
A restart-on-exit policy may not activate because the main process has not exited. Check the journal and YouTube Live Control Room, then consider whether FFmpeg output recovery or a separate progress watchdog is appropriate. Any watchdog needs a meaningful progress signal and should be tested before you rely on it.
How do I know recovery worked?
Check both sides: systemd status and journal output should show the service running, and YouTube Live Control Room should show the expected broadcast arriving. If the service is active but the platform reports an error, treat that as an unresolved ingest or stream issue rather than proof of a successful recovery.