Launchd won't load plists at boot I have a set of scripts that need to run on system boot and stay alive. I have the plist saved as /Library/LaunchAgents/net.vps.tunnel.plist and it has the proper permissions:

-rw-r--r--  1 root  wheel  516 Nov  6 22:03 net.vps.tunnel.plist


The script is stored in the root /Library/LaunchAgents, NOT the user ~/Library/LaunchAgents directory, so it's supposed to run on boot as the superuser. If I manually run the script via sudo launchctl load /Library/LaunchAgents/net.vps.tunnel.plist it runs fine. But despite the fact that it is supposed to run on boot, it doesn't. When I check launchctl list immediately after boot, I see that it has not been loaded. Trying to start via sudo launchctl start net.vps.tunnel fails with the error "launchctl start error: No such process".

If I log in via the GUI, suddenly launchd loads all of the scripts. However, they run with my user permissions and some of them do not work properly. In the plists, I have specified the UserName key as a daemon user, but they all run under my user credentials.

Here's the plist file in question, located at /Library/LaunchAgents/net.vps.tunnel.plist and with -rw-r--r-- permissions for root:wheel:

&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE plist PUBLIC -//Apple Computer//DTD PLIST 1.0//EN http://www.apple.com/DTDs/PropertyList-1.0.dtd &gt;
&lt;plist version="1.0"&gt;
&lt;dict&gt;
        &lt;key&gt;Label&lt;/key&gt;
                &lt;string&gt;net.vps.tunnel&lt;/string&gt;
        &lt;key&gt;ProgramArguments&lt;/key&gt;
                &lt;array&gt;
                        &lt;string&gt;/Users/_tunnel/tunnel.sh&lt;/string&gt;
                &lt;/array&gt;
        &lt;key&gt;RunAtLoad&lt;/key&gt;
                &lt;true/&gt;
        &lt;key&gt;WorkingDirectory&lt;/key&gt;
                &lt;string&gt;/Users/_tunnel&lt;/string&gt;
        &lt;key&gt;UserName&lt;/key&gt;
                &lt;string&gt;_tunnel&lt;/string&gt;
        &lt;key&gt;KeepAlive&lt;/key&gt;
                &lt;true/&gt;
&lt;/dict&gt;
&lt;/plist&gt;


And here's the tunnel script, with permissions -rwxr-x--- for _tunnel:_tunnel:

#/bin/bash

logger "Opening VPS tunnel..."

ssh -i ./.ssh/id_rsa -gnN tunnel@********.com &amp;
PID=$!
logger "VPS tunnel is now open."

wait $PID
logger "VPS tunnel is now closed."
exit 0
Try moving the plist to /Library/LaunchDaemons/. Agents (other than pre-login agents) are run only after a user logs in and they are owned by the user. Also the UserName key has no effect for agents.

See the Daemons and Agents tech note.