# lxmd and rnsd service

_Help · started by Anonymous on Thu, Mar 19, 2026 7:43 PM_

Tags: Question, LXMF

---

## Original post

**Anonymous** · Thu, Mar 19, 2026 7:43 PM

Hi,

can you share how your rnsd+lxmd setup looks like? I currently have both running as systemd service files, but on bootup lxmd does not boot properly for some reason. I have to stop it and then start it again so it works.

Here are my service files:

lxmd:
```
# /etc/systemd/system/lxmd.service
[Unit]
Description=LFXC daemon propagation node
Requires=rnsd.service
After=rnsd.service

[Service]
Type=simple
Restart=always
RestartSec=3
User=rns
ExecStart=/home/rns/.local/bin/lxmd --propagation-node --service

[Install]
WantedBy=multi-user.target
```

and rnsd:
```
# /etc/systemd/system/rnsd.service
[Unit]
Description=Reticulum Network Stack Daemon
After=multi-user.target

[Service]
# If you run Reticulum on WiFi devices,
# or other devices that need some extra
# time to initialise, you might want to
# add a short delay before Reticulum is
# started by systemd:
# ExecStartPre=/bin/sleep 10
Type=simple
Restart=always
RestartSec=3
User=rns
ExecStart=/home/rns/.local/bin/rnsd --service

[Install]
WantedBy=multi-user.target
```

---

## Reply 1

**LinuxinaBit** · Thu, Mar 19, 2026 8:53 PM

To troubleshoot, it's worth running:
```
systemctl status lxmd.service
```


I recommend just starting NomadNet with systemd and letting it handle the rest.
To start nomadnet in daemon mode, use:
```
nomadnet --daemon
```

---

## Reply 2

**Anonymous** · Fri, Mar 20, 2026 8:34 PM

I am a bit confused how the daemons work with each other, maybe because the documentation is very bare on this side. You mean by starting nomadnet it would also start rnsd and a propagation node?

---

## Reply 3

**Anonymous** · Fri, Mar 20, 2026 9:33 PM

Aha, I see. lxmd seems to start up rnsd automatically. I removed the rnsd service file and instead start now only lxmd. seems to work.

---

## Reply 4

**Basil** · Tue, Mar 24, 2026 5:33 PM

hi!!, for rnsd, i use
[Unit]
Description=Reticulum Network Stack Daemon
After=network.target

[Service]
ExecStart=<folderwherernsislocatedin>/rnsd
Restart=always
User=<yourusername>

[Install]
WantedBy=multi-user.target

---

## Reply 5

**aaaa** · Sat, Mar 28, 2026 6:48 PM

test

---

## Reply 6

**K8** · Thu, Apr 16, 2026 4:24 AM

None of these are reliable options. You need to watch the logs to know when RNS is fully started and it's ok to start lxmd and NomadNet. To do that you need wrapper scripts that fork off the rnsd process and don't end themselves until the logs indicate that RNS is fully started. This allows you to use the systemd functionality for making sure the different services start in sequence, without having to rely on timers which will get flaky when RNS has to load a lot of path table entries on startup.

**`/etc/systemd/system/rnsd.service`**:
```ini
[Unit]
Description=Reticulum rnsd Service
After=network-online.target
Requires=network-online.target
StartLimitIntervalSec=60
StartLimitBurst=4

[Service]
Type=forking
ExecStart="/path/to/start_rnsd.sh"
ExecStop="/path/to/stop_rnsd.sh"
Restart=always
RestartSec=3
Nice=-10
Environment="PYTHONPATH='/home/rns/Reticulum':'/home/rns/LXMF':'/home/rns/NomadNet'"
WorkingDirectory=~
User=rns
Group=reticulum

[Install]
WantedBy=multi-user.target
```

**`start_rnsd.sh`**:
```bash
#!/bin/bash

set -e

LOG="/path/to/reticulum/logfile"

LOGLINES=0
if [ -f $LOG ]; then
    LOGLINES=$(wc -l < $LOG)
fi

echo "Starting rnsd service"

export PYTHONPATH='/home/rns/Reticulum':'/home/rns/LXMF':'/home/rns/NomadNet'
python3 -m "RNS.Utilities.rnsd" --service --config "/home/rns/config/reticulum" &

echo "Waiting for rnsd service to fully start"
while true; do
    NEWLOGLINES=$(wc -l < $LOG)
    if [ "$NEWLOGLINES" -lt "$LOGLINES" ] ; then
        # The log must have rotated since the start of the script
        TAILCMD="cat $LOG"
    else
        TAILCMD="tail -n +$LOGLINES $LOG"
    fi

    if $($TAILCMD | grep -q -E "Started rnsd"); then
        break
    else
        sleep 1
    fi
done

echo "Started rnsd service"
```

**`stop_rnsd.sh`**
```bash
#!/bin/bash

set -e

LOG="/path/to/reticulum/logfile"

LOGLINES=0
if [ -f $LOG ]; then
    LOGLINES=$(wc -l < $LOG)
fi

echo "Stopping rnsd service"
kill $MAINPID

echo "Waiting for rnsd service to fully shut down"
while true; do
    NEWLOGLINES=$(wc -l < $LOG)
    if [ "$NEWLOGLINES" -lt "$LOGLINES" ] ; then
        # The log must have rotated since the start of the script
        TAILCMD="cat $LOG"
    else
        TAILCMD="tail -n +$LOGLINES $LOG"
    fi

    if $($TAILCMD | grep -q -E "Saved known destinations to storage"); then
        break
    else
        sleep 1
    fi
done

echo "Stopped rnsd service"
```

Note that I run my node from source for easier development, so you'll have to change the command to run rnsd to whatever you need for your environment, and you can also remove the `Environment=...` line from the service file.

The lxmd service definition will look similar, but depending on the rnsd service:

```ini
After=rnsd.service
Requires=rnsd.service
```

And the start and stop scripts should grep for "Started lxmd" and "All interfaces detached", respectively (and naturally should be changed to run the right command).

For NomadNet, grep for "ready for incoming connections" and "Persisting LXMF state data to storage".

I have all of this abstracted in an Ansible playbook that I use to deploy my public node. I will release it at some point, once I get things cleaned up and documented a bit.

---

## Reply 7

**Anonymous** · Thu, Apr 16, 2026 7:43 AM

Thank you for sharing! This is more complicated then I hoped ^^ but makes sense that it will work that way.

---

## Reply 8

**joakim** · Thu, Apr 16, 2026 8:34 AM

I just check for port 4242 being open before starting `lxmd`. In `lxmd.service`:

```
ExecStartPre=/usr/bin/bash -c '(while ! ss -lnt sport = :4242 | grep 4242 2>/dev/null; do echo "Waiting for port 4242 to open..."; sleep 3; done); sleep 3'
```

K8's solution is more thorough though, and I would think more reliable. The port being open doesn't necessarily mean that `rnsd` is ready, so YMMV, but it has worked well for me so far.

---

## Reply 9

**joakim** · Thu, Apr 16, 2026 8:55 AM

**Anonymous** wrote:
> I am a bit confused how the daemons work with each other, maybe because the documentation is very bare on this side. You mean by starting nomadnet it would also start rnsd and a propagation node?

It's explained here: https://reticulum.miraheze.org/wiki/RNS#Shared_instance

Running (only) `lxmd` sounds like the right choice for you. `nomadnet` seems to have memory leaks, so I'd not run that as a daemon unless I also needed to serve pages/files.

Running `rnsd` first makes sense in some situations. From the manual:
> If you are running Reticulum on a system with several different programs that use RNS starting and terminating at different times, it will be advantageous to run a master RNS instance as a daemon for other programs to use on demand.

---

## Reply 10

**Anonymous** · Sat, Apr 18, 2026 8:36 PM

> And the start and stop scripts should grep for &quot;Started lxmd&quot; and &quot;All interfaces detached&quot;, respectively (and naturally should be changed to run the right command).
> 
> For NomadNet, grep for &quot;ready for incoming connections&quot; and &quot;Persisting LXMF state data to storage&quot;.

You got NomadNet and lxmd mixed up there, but otherwise, nice!

---

## Reply 11

**Cleeyv** · Mon, Apr 20, 2026 8:40 PM

I encountered a very similar problem when trying to run an rnsd.service and a rnsh.service, basically the same setup you're describing here but with rnsh instead of lxmd. After hours of debugging, I finally figured out that it seemed to be some kind of systemd dependency loop that blocked the second service (lxmd or rnsh) from being started automatically. The solution that worked for me was to remove the line `After=multi-user.target` from the rnsd.service file and then everything worked as I wanted it to. It is also possible that the version of this problem I encountered is different than it would be elsewhere because it was with the resource constraints of a little RPi Zero 2w.

Another tip is that the debugging step that was most helpful for me to figure out what was going on was to enable `LogLevel=debug` in /etc/systemd/system.conf which gave more traces in `journalctl -b` of the interactions between the two services during boot.

Hopefully this is helpful to you and others with similar problems. It makes me wonder if there could be reason to remove or modify (or at least add a comment note) to the manual's template for an rnsd.service file that includes `After=multi-user.target`: https://github.com/markqvist/Reticulum/blob/master/docs/manual/using.html#L1234 but maybe there are other reasons for it to be there that I'm less aware of and would make the decision to change or remove it more complicated.

---

## Reply 12

**Anonymous** · Mon, Apr 20, 2026 10:42 PM

**Cleeyv** wrote:
> I encountered a very similar problem when trying to run an rnsd.service and a rnsh.service, basically the same setup you&#039;re describing here but with rnsh instead of lxmd. After hours of debugging, I finally figured out that it seemed to be some kind of systemd dependency loop that blocked the second service (lxmd or rnsh) from being started automatically. The solution that worked for me was to remove the line `After=multi-user.target` from the rnsd.service file and then everything worked as I wanted it to. It is also possible that the version of this problem I encountered is different than it would be elsewhere because it was with the resource constraints of a little RPi Zero 2w.
> 
> Another tip is that the debugging step that was most helpful for me to figure out what was going on was to enable `LogLevel=debug` in /etc/systemd/system.conf which gave more traces in `journalctl -b` of the interactions between the two services during boot.
> 
> Hopefully this is helpful to you and others with similar problems. It makes me wonder if there could be reason to remove or modify (or at least add a comment note) to the manual&#039;s template for an rnsd.service file that includes `After=multi-user.target`: https://github.com/markqvist/Reticulum/blob/master/docs/manual/using.html#L1234 but maybe there are other reasons for it to be there that I&#039;m less aware of and would make the decision to change or remove it more complicated.

You could message mark about it. Or maybe even better, we could create a page on the community wiki about running rnsd etc as a service?

---

## Reply 13

**Anonymous** · Tue, Apr 21, 2026 5:54 PM

@Anonymous#11  I think that part is correct. The different services all have inconsistent log output and those messages are the closest I was able to get the the real start and end (even though for NomadNet the last log message is talking about LXMF).

---

## Reply 14

**Anonymous** · Sun, May 3, 2026 11:42 PM

**Anonymous** wrote:
> Hi,
> 
> can you share how your rnsd+lxmd setup looks like? I currently have both running as systemd service files, but on bootup lxmd does not boot properly for some reason. I have to stop it and then start it again so it works.
> 
> Here are my service files:
> 
> lxmd:
> ```
> # /etc/systemd/system/lxmd.service
> [Unit]
> Description=LFXC daemon propagation node
> Requires=rnsd.service
> After=rnsd.service
> 
> [Service]
> Type=simple
> Restart=always
> RestartSec=3
> User=rns
> ExecStart=/home/rns/.local/bin/lxmd --propagation-node --service
> 
> [Install]
> WantedBy=multi-user.target
> ```
> 
> and rnsd:
> ```
> # /etc/systemd/system/rnsd.service
> [Unit]
> Description=Reticulum Network Stack Daemon
> After=multi-user.target
> 
> [Service]
> # If you run Reticulum on WiFi devices,
> # or other devices that need some extra
> # time to initialise, you might want to
> # add a short delay before Reticulum is
> # started by systemd:
> # ExecStartPre=/bin/sleep 10
> Type=simple
> Restart=always
> RestartSec=3
> User=rns
> ExecStart=/home/rns/.local/bin/rnsd --service
> 
> [Install]
> WantedBy=multi-user.target
> ```

Just run a simple lxmd startup script and that will bring up rnsd automatically. This is what I use:

[Unit]
Description=Lightweight Extensible Message Daemon
After=multi-user.target

[Service]
# If you run Reticulum on WiFi devices,
# or other devices that need some extra
# time to initialise, you might want to
# add a short delay before Reticulum is
# started by systemd:
# ExecStartPre=/bin/sleep 10
Type=simple
Restart=always
RestartSec=3
User=liberty
ExecStart=lxmd --service

[Install]
WantedBy=multi-user.target

---
