ENGINEERING · April 16, 2026 · 11 min read
Handling SharePoint blocked file types without breaking your migration
Here is a migration verdict that quietly causes support tickets. A batch finishes, 42,091 files are in the destination, a hundred or so files are in a “failed” bucket that includes Windows_Driver.exe, installer-build-2471.msi, and config.aspx. The user reads “failed” and opens a ticket. Why did this fail? Can you retry it? The operator digs in, discovers that two of these files failed for one reason, the third failed for a completely different reason, and neither is going to succeed no matter how many times you retry.
The problem is not that the migration broke. The problem is that the verdict lumps three outcomes into one. Blocked at source, blocked at destination, and genuinely failed are not the same thing — they need different handling, different messaging, and different retry logic. Splitting them apart is the difference between a clean client sign-off and a week of follow-up tickets.
Two separate blocking problems
When you move data between cloud platforms, “blocked file type” is not a single concept. There are two different systems with different rules, and it matters which one stops a given file.
1. Google Drive’s malware download policy
Google inspects every file on upload and classifies some of them as potentially harmful — most commonly Windows executables (.exe, .msi), dynamic libraries (.dll), shell scripts, and a handful of other binary formats. Files that trip the policy can still live in Drive (Google does not delete them), but files.get?alt=media will refuse to serve the content unless the caller sets an acknowledgeAbuse=true flag. That flag cannot be set unconditionally — Google requires the request to come from a user who owns the file, and for many service-account migration flows the ownership chain does not satisfy the policy.
The practical effect: certain files in a Google Drive source cannot be downloaded by the migration engine no matter what SharePoint’s tenant policy says. The file is “blocked” but the blocker is the source, not the destination.
2. SharePoint tenant blocked file types
Every SharePoint tenant has a list of file extensions that cannot be uploaded. The list is configured by tenant admins. The default list is small and mostly consists of executables and server-scripting extensions (.aspx, .asmx, .ashx, .master, .htc, .soap). Many organisations relax this list — for example, an engineering tenant that hosts build artefacts will explicitly allow .exe and .dll.
The blocked list changes per tenant. It changes over time. It changes for specific site collections. There is no way to know what a given tenant blocks without asking the tenant, and there is no universal set of extensions that is safe to assume will always be rejected.
Why a hardcoded extension list is the wrong approach
The intuitive design for a migration tool is a pre-flight hardcoded list of SharePoint’s default blocked extensions. Files matching the list get skipped before any upload is attempted. The theory is kind — save a round trip to SharePoint, produce a nicer verdict up front. The practice is not kind.
- False positives on relaxed tenants. An engineering tenant that has explicitly allowed
.ps1sees those files silently dropped by the pre-flight, with a log line that says “blocked at destination” — even though the destination would have accepted them. The operator has no way to know the tool is wrong. - False negatives on tightened tenants. A finance tenant that has blocked
.isosees those files pass the pre-flight, get uploaded, get rejected by SharePoint, and show up in the failed bucket. Retries do nothing. The operator is left hunting for a cause. - Drift with Microsoft’s default list. Microsoft occasionally adds or removes extensions from the platform default. Any hardcoded list goes stale the day Microsoft updates theirs.
The fix is structural: stop guessing, start asking. The tenant is the source of truth for what it accepts. Read the live blocked list from the tenant before the migration starts, and trust it.
The correct flow
The sequence for any file should be:
- Scan enumerates the source. Every file, every extension, no extension-based filtering.
- Scan queries the destination tenant’s blocked list. For SharePoint destinations the tenant-admin REST endpoint returns the live policy; for targets where that endpoint is not available, the migration probes for upload rejections to derive the same list.
- Scan report shows the expected skip counts up front. The operator sees “12 files will be rejected by tenant policy” before starting, with the specific extensions and tenant policy listed.
- Migration runs. When a source-side download is refused by Google Drive’s malware policy, the file is classified
SKIPPED-source-blockedwith the reason “Google Drive malware policy.” When an upload returns a 400 with the SharePoint blocked-file-type error code, the file is classifiedSKIPPED-dest-blockedwith the reason “tenant blocks .aspx.” - Only transient or unexpected errors become
FAILED. Network timeouts, throttle exhaustion after max retries, malformed content, storage quota — the things a retry or an operator decision can actually address.
Why skipped-not-failed matters
The distinction between SKIPPED and FAILED is more than aesthetic. A FAILED job implies a defect in the migration — something went wrong that should not have. A sensible operator retries. The retry consumes budget. If the cause was a policy decision the retry is pure waste.
A SKIPPED job implies a conscious exclusion — the file was excluded by a rule outside the migration’s control. A sensible operator does not retry; they either adjust the rule (relax tenant policy, copy the file manually via a different channel) or accept the skip and document it.
Labelling the outcome correctly removes an entire category of wasted operator time, and it makes the verdict panel something a client can sign off without follow-up questions. “Why did 89 files fail?” becomes “89 files were skipped by your own tenant policy — here are the extensions; if you want them migrated, relax policy and re-run.”
SharePoint’s default blocked list (for reference)
For teams that want to know the baseline before their tenant admin customises anything, the default list Microsoft ships is:
| Extension | Why it is blocked by default |
|---|---|
.aspx .asmx .ashx | Server-side SharePoint page handlers — risk of uploaded content being executed as server code |
.master | SharePoint master page — controls site chrome, a replacement can compromise the site |
.htc | HTML component — runs script in IE-era contexts; still flagged for compatibility |
.soap | SOAP message — associated with legacy SharePoint service endpoints |
.shtm .shtml .stm | Server-parsed HTML — historic web-server execution paths |
.dll .exe .msi | Windows binaries — malware vector, not tied to SharePoint specifically but blocked at platform level |
.config | .NET configuration — blocked to prevent SharePoint behaviour overrides |
.ps1 .psm1 .ps1xml | PowerShell — executable script, administrative risk |
.vbs .wsf .jse .vbe | Windows Script Host formats — legacy malware vector |
Microsoft has trimmed this list over the years. Several extensions that used to be blocked by default (.html, .htm, .js, .jar) were removed as SharePoint’s execution model moved to client-side rendering and became safer. The exact current default is only authoritative by reading it from the tenant directly.
Relaxing the policy if you need it
If your organisation legitimately needs some of these extensions in SharePoint — an engineering team that ships .exe builds, a DevOps team that stores .ps1 scripts — a tenant admin can relax the list in the SharePoint admin centre under Settings → More features → SharePoint admin center → Policies → Blocked file types. Changes take effect within a few minutes across the tenant.
Two recommendations if you go this route. First, relax per site collection where possible instead of the whole tenant. The admin centre allows a site-level override so that your engineering hub accepts .exe while your finance sites continue to reject them. Second, document the relaxation in your migration run-book — if someone re-tightens the policy a month later, they will not know why the original relaxation existed, and the next migration will surprise them.
The Google Drive side
For the source-blocked case the solution is simpler but less satisfying: no migration tool can unilaterally make Google serve a file its malware policy has flagged. The options for the customer are:
- Acknowledge the abuse flag per file. The file owner can download the file through the Google Drive web UI and re-upload to SharePoint manually. This is the right path for a handful of files a customer genuinely wants to preserve.
- Accept the skip. Most
.exeand.msifiles in a long-lived Drive are outdated installers for software the user no longer runs. The skipped file list usually includes several of these. The skip is the right outcome. - Escalate through Google Workspace admin. For corpus-level policy adjustments an admin can negotiate policy changes for the tenant. This is not a common path and is rarely worth the effort for isolated files.
In all three cases the verdict should be SKIPPED-source-blocked, the report should explain why, and the retry button should not be offered — because retry does not help.
What a four-column verdict looks like
A migration report with the right structure shows four columns instead of two: Completed, Skipped-Source, Skipped-Destination, Failed. Each column is clickable to drill into the full list. Each skip is annotated with its policy reason. For client sign-off documents, the split makes the conversation cleaner:
- Completed: “42,091 files are in SharePoint. Your content is migrated.”
- Skipped-source: “14 files could not be downloaded from Google Drive due to their malware policy. These are listed for your review.”
- Skipped-destination: “89 files were rejected by your SharePoint tenant’s blocked-file-types policy. To migrate these, either relax policy and re-run, or handle out of band.”
- Failed: “47 files had transient errors. The migration tool will retry these automatically.”
Related reading
- Why your SharePoint migration stalls at 99%
- Why .DS_Store and Thumbs.db slow down your migration
- Migration Rehearsal: the dry-run that tells you what breaks
Get started
Run a migration with live tenant-policy detection at app.migrationfox.com/register. The four-column verdict panel is on by default for every workspace.