launchd – How can I debug a user LaunchAgent that doesn’t seem to start or load with launchctl?

Problem Description

Running the following user LaunchAgent does not show a started job, nor does the job log an error or do anything detectable. The Vault commands embedded in the plist file work fine when run from a user crontab or the command line, though. I’ve run the following commands as a non-root user:

# returns exit status 3
launchctl start local.localhost.RenewVaultToken.plist
echo $?

# also returns exit status 3
launchctl enable gui/$UID/local.localhost.RenewVaultToken
launchctl start gui/$UID/local.localhost.RenewVaultToken
echo $?

# returns "Load failed: 5: Input/output error"
launchctl load gui/$UID/local.localhost.RenewVaultToken

# no results
launchctl list | fgrep -i vault

Tailing the system log doesn’t show anything identifiable, nor are any log files created. As far as I can tell, the job can’t/won’t start or run, but I’m not sure how to effectively debug it further.

LaunchAgent File Contents

I have the following file stored in ~/Library/LaunchAgents with the filename local.localhost.RenewVaultToken.plist. The file is set to mode 0600.

<?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">

<!-- ~/Library/LaunchAgents/local.localhost.RenewVaultToken.plist -->
<plist version="1.0">
    <dict>
        <key>Label</key>
        <string>local.localhost.RenewVaultToken</string>

        <key>ProgramArguments</key>
        <array>
            <string>/usr/local/bin/vault</string>
            <string>token</string>
            <string>renew</string>
            <string>-increment=12h</string>
            <string>-address="https://vault.example.com"</string>
        </array>

        <key>StartInterval</key>
        <integer>14400</integer>

        <key>RunAtLoad</key>
        <true/>

        <key>Debug</key>
        <true/>

        <key>StandardOutPath</key>
        <string>/Users/foo/stdout.log</string>

        <key>StandardErrorPath</key>
        <string>/Users/foo/stderr.log</string>
    </dict>
</plist>