Important note: The machine you call "local machine" is totally irrelevant. The real story begins when you're already on
100.100.100.1. In the context of
scp and in the context of this answer "local" is the machine where
scp is invoked by you.
Why does the first [command] fail?
You tried to copy between two (formally) remote hosts.
email@example.com:/path/1/ as a non-local path. It doesn't matter
firstname.lastname@example.org points to the local machine. The tool doesn't (and shouldn't) check if an address that looks remote points to the local machine. Just by referring to the source as if it was remote, you made
scp treat it as remote. Also the destination was remote.
Copying between two remote hosts can be done with or without the
Copies between two remote hosts are transferred through the local host. Without this option the data is copied directly between the two remote hosts. […]
(emphasis mine, source)
The bold fragment applies to your case (even if your
scp doesn't support
If you use
-v with your first command
scp -v -i ~/keyfile -r email@example.com:/path/1/ firstname.lastname@example.org:/path/2/
you will see
scp connects from the local host to the source host ("incidentally" being the same host) using the key specified with
-i. (Apparently the host is configured to accept this key, probably because the other server uses an identical key to connect.)
Then you will see another
scp is invoked on the source host. The command is:
scp -v -r /path/1/ email@example.com:/path/2/
-r are there because they were in your local command. The source path is translated to a local path; the destination is unchanged. If this command run successfully, the data would be "copied directly between the two remote hosts".
Note there is no
-i ~/keyfile be there? Or rather
-i /home/cindy/keyfile or so? (because the local
scp got something like this after the local shell expanded the tilde).
No. In general a remote source host may be (and usually is) different than the local host. A path that is valid for the local host may point to anything or nothing on the remote host. If
scp on the source host was invoked with
-i, it would cause more problems than it could solve. It's a good thing
-i does not propagate to the command invoked on the source host. But then the host connects to the destination using its default key or whatever its configuration tells it to use.
In your case it appears one needs the local
~/keyfile to connect to the destination host. The source host holds the right file (because in this particular case the local and the source are the same machine), but the
scp command that actually connects to the destination lacks
-i (as it should in general) and therefore the key is not used.
Your second command used a local path as a source, only the destination was remote. In this case the key specified with
-i was used to connect from the local host to the destination host, exactly as you planned. Therefore it worked.
Note if you configured the local machine to automatically use
~/keyfile to connect to the other server (
~/.ssh/config), then the first command would work. The local host would unnecessarily connect to itself, only to tell itself to connect to the destination, but still it would work. The first connection would use
~/keyfile because of
-i, the second connection would use
~/keyfile because of the configuration.