If the read callback doesn't fill up the entire buffer, that is considered the end of the transfer by the TFTP server. This can easily happen when uploading from stdin.
Serj Kalichev posted a patch for this problem here
TFTP: Fix upload problem with piped input
When input stream for curl is stdin and input stream is not a file but
generated by a script then curl can truncate data transfer to arbitrary
size since a partial packet is treated as end of transfer by TFTP.