Can't start tftpd because port is already in use by launchd

Enabling tftpd

sudo launchctl load -F /System/Library/LaunchDaemons/tftp.plist

Start:

sudo launchctl start com.apple.tftpd

See logs syslog -w

com.apple.xpc.launchd[1] (com.apple.tftpd[30687]) <Warning>: Service exited with abnormal code: 1

Or with log stream --process tftp --level debug

Filtering the log data using "process BEGINSWITH[cd] "tftp""
Timestamp                       Thread     Type        Activity             PID    TTL
2020-01-21 12:35:44.903240+0200 0x5292a    Activity    0x6afa0              31479  0    tftpd: (libsystem_info.dylib) Retrieve User by Name
2020-01-21 12:35:44.903949+0200 0x5292a    Default     0x0                  31479  0    tftpd: recvfrom: Resource temporarily unavailable

I also tried to run tftpd directly without launchctl sudo /usr/libexec/tftpd -d -i /private/tftpboot/ with the same results.

Earlier I used this configuration and it worked fine. But after some changes (may be OS update) it became broken.
Current MacOS version is 10.14.6 (18G2022)

How to fix tftpd?


Appendix.
Configuration file /System/Library/LaunchDaemons/tftp.plist has default content:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Disabled</key>
    <true/>
    <key>Label</key>
    <string>com.apple.tftpd</string>
    <key>ProgramArguments</key>
    <array>
        <string>/usr/libexec/tftpd</string>
        <string>-i</string>
        <string>/private/tftpboot</string>
    </array>
    <key>inetdCompatibility</key>
    <dict>
        <key>Wait</key>
        <true/>
    </dict>
    <key>InitGroups</key>
    <true/>
    <key>Sockets</key>
    <dict>
        <key>Listeners</key>
        <dict>
            <key>SockServiceName</key>
            <string>tftp</string>
            <key>SockType</key>
            <string>dgram</string>
        </dict>
    </dict>
</dict>
</plist>

Update1
It seems port is in use. Why? Who?

$ sudo lsof -i:69
COMMAND PID USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
launchd   1 root   23u  IPv6 0x55f5dbd8d897c847      0t0  UDP *:tftp
launchd   1 root   57u  IPv4 0x55f5dbd8d897e687      0t0  UDP *:tftp
launchd   1 root   59u  IPv6 0x55f5dbd8d897c847      0t0  UDP *:tftp
launchd   1 root   60u  IPv4 0x55f5dbd8d897e687      0t0  UDP *:tftp

launchd uses UDP port 69. Why?

$ ps -ef | grep tftp
501 94727 48073   0  4:16PM ttys007    0:00.00 grep --color=auto tftp

Solution 1:

These steps solved my problem

  1. Reload plist

    sudo launchctl unload -F /System/Library/LaunchDaemons/tftp.plist
    sudo launchctl load -F /System/Library/LaunchDaemons/tftp.plist
    
  2. (Re)enable service

    sudo launchctl disable system/com.apple.tftpd
    sudo launchctl enable system/com.apple.tftpd
    
  3. Start service (or restart)

    sudo launchctl start com.apple.tftpd
    

Thank you everyone who participated in discussion, especially @Prado

Solution 2:

Your question is why launchd uses UDP port 69. This is basically because you've just told it to do so in the plist file, you've quoted in your question. If you're not used to launchd or similar programs on Unix-systems, it might seem counterintuitive - but this is how things are supposed to work.

Basically launchd does not start the tftpd server program at boot or when you login. Instead it opens port 69 and waits for someone to actually contact the tftp service - only when it is actually going to be used by someone, launchd starts the tftpd server program and hands over the traffic to that program.

Therefore it is as intended that port 69 is in use by launchd.