Looking at the Net::SFTP::Foreign Source, it would appear that callback is not a valid option for mput():
sub mput {
...
my ($sftp, $local, $remotedir, %opts) = @_;
...
my $ignore_links = delete $opts{ignore_links};
my %glob_opts = (map { $_ => delete $opts{$_} }
qw(on_error follow_links ignore_case
wanted no_wanted strict_leading_dot));
...
my %put_opts = (map { $_ => delete $opts{$_} }
qw(umask perm copy_perm copy_time block_size queue_size
overwrite conversion resume numbered late_set_p
+erm
atomic best_effort sparse));
%opts and _croak_bad_options(keys %opts);
...
However, put() does accept callback (as well as copy_perm and copy_time):
sub put {
...
my $cb = delete $opts{callback};
...
my $copy_perm = delete $opts{copy_perm};
...
my $copy_time = delete $opts{copy_time};
...