I've finally figured out what on earth the driver is doing! I had entirely given up on ever being able to use my SpaceMouse in OnShape again, until I unexpectedly noticed 3DxNLServer showing up in Activity Monitor on my mac mini, and I realized I could binary search through my config until I worked out what was different between the systems.
3DxNLServer binds 127.51.68.120:8181, which will fail if this IP is not currently associated to any interface on the system. Thankfully (for my sanity), I can replicate this failure:
Code: Select all
❯ python3
Python 3.14.0 (main, Oct 7 2025, 09:34:52) [Clang 17.0.0 (clang-1700.0.13.3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import socket
>>> server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
>>> server.bind(("127.51.68.120",8181))
Traceback (most recent call last):
File "<python-input-2>", line 1, in <module>
server.bind(("127.51.68.120",8181))
~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^
OSError: [Errno 49] Can't assign requested address
We need to link this IP to a network interface, in particular the loopback interface lo0, which we can do like so:
Code: Select all
sudo /sbin/ifconfig lo0 alias 127.51.68.120 up
and then see the IP properly associated, via ifconfig:
Code: Select all
❯ ifconfig
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384
options=1203<RXCSUM,TXCSUM,TXSTATUS,SW_TIMESTAMP>
inet 127.0.0.1 netmask 0xff000000
inet6 ::1 prefixlen 128
inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1
inet 127.51.68.120 netmask 0xff000000
nd6 options=201<PERFORMNUD,DAD>
...
At which point we can bind 127.51.68.120:8181, and so can 3DxNLServer as confirmed by a much more desirable log message in Console:
Code: Select all
<timestamp>: Http and Websocket server successfully started
It's not clear to my why 3DxNLServer is not able to directly check for and optionally create this IP link when it runs, but it turns out there is a configuration installed on the system as part of the SpaceMouse driver install process. This is the file /Library/LaunchDaemons/com.3dconnexion.nlserverIPalias.plist, which contains this:
Code: Select all
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.3dconnexion.nlserverIPalias</string>
<key>RunAtLoad</key>
<true/>
<key>ProgramArguments</key>
<array>
<string>/sbin/ifconfig</string>
<string>lo0</string>
<string>alias</string>
<string>127.51.68.120</string>
<string>up</string>
</array>
</dict>
</plist>
So why wasn't it configured on my system? Because of years of random junk installed on my machine and my obsession with disabling LaunchDaemons that I don't specifically understand and want to run. At some point, I had toggled off this seemingly random entry called "ifconfig" under Login Items and Extensions in my System Settings:

- ifconfig.png (24.44 KiB) Viewed 356 times
Toggling it on (or better yet, Loading it via LaunchControl, which is how I initially identified ifconfig as a critical 3dconnexion config), allowed 3DxNLServer to start successfully after a reboot.
I'm so happy to have this fixed, and I think it would be great if the server app could handle this configuration automatically, or at least detect and log it.