An Azure service that stores unstructured data in the cloud as blobs.
Hi Nassim Cherifi,
Thanks for posting question in Microsoft Q&A,
Workaround 1:
Workaround 1 creates a private endpoint for the destination storage account directly in the source VNet (Spoke A), resolving the 403 "CannotVerifyCopySource" error in hub-spoke topologies. This allows the VM in the Hub VNet to successfully trigger server-side copies via AzCopy.
AzCopy issues a Put Block From URL request to the destination storage service, providing the source blob URL. The destination service attempts to fetch blocks directly from the source storage over Azure's internal backbone (server-side copy, no client bandwidth used).
If the source firewall rejects this (due to private endpoints and no direct trust), the destination falls back to proxy mode: it requests the client (VM) perform Get Blob from source and Put Block to destination. Your assumption is correct traffic isn't "initiated by the private endpoint"; the destination storage service starts the source fetch internally.
Why It Succeeds Post-Workaround
- VM (Hub) accesses source via existing Spoke A private endpoint (VNet peering enables reachability).
- VM accesses destination via new private endpoint in same Spoke A VNet.
- Proxy fallback authenticates via VM's permissions; no source firewall block on destination service since client-proxied path bypasses direct service-to-service check.
This scales better than Workaround 4 (VM download/upload) by preferring efficient server-side copy.
Yes, your assumption is correct. Private endpoints do not initiate traffic themselves; they serve as network interfaces that map private IP addresses within the VNet to the storage service, enabling inbound connections from authorized clients or services in that VNet.
Update:
The Problem (Different VNets)
VM → Source (VNet A) > Works
VM → Destination (VNet B) ? Works separately
But PutBlockFromURL proxy needs BOTH at the SAME TIME > Fails
Destination storage expects your VM to talk to it through its specific private endpoint during the proxy session. Cross-VNet routing confuses this session.
The Fix (Workaround 1)
Put Destination endpoint in Source VNet (Spoke A):
VM → Spoke A VNet → [Source PE + Dest PE together] > Works!
Workaround 4 succeeds because it doesn't need this coordination—just simple download from source.
Your ER routing is fine. Proxy just needs both endpoints in same VNet for the "handshake" to work.
Check NSG logs on destination endpoint during copy attempt you'll see the connection drops.
Please do not forget to
and “up-vote” wherever the information provided helps you, this can be beneficial to other community members.