|
By: Paul S Cilwa |
Posted: 3/26/2026 |
|
Page Views: 206 |
| Hashtags: #Windows #Security #Development #Programming #VisualStudio #OneDrive #MOTW #MarkOfTheWeb |
| Windows' Zone.Identifier alternate data stream flags downloaded files as untrusted, causing endless headaches for developers. |
| Estimated reading time: 7 minute(s) (1442 words) |
What Is It?
Every time you download a file from the
internet—or receive one via email, or sync one from
OneDrive, or copy one from a network share—Windows
quietly attaches a hidden alternate data stream (ADS)
called Zone.Identifier to the file. This is
an NTFS feature that lets files carry extra metadata that
doesn't show up in Explorer, doesn't appear when you open
the file, and doesn't get listed by the dir
command.
The contents of this stream are deceptively simple. If
you were to peek at it (using PowerShell's
Get-Content -Stream Zone.Identifier), you'd
see something like:
[ZoneTransfer]
ZoneId=3
That ZoneId=3 means "Internet zone." Other
values include 0 (Local), 1 (Intranet), 2 (Trusted), and
4 (Restricted). But in practice, 3 is the one you'll see
on virtually everything that causes problems.
This little tag is what Microsoft calls the "Mark of the
Web," or MOTW for short.
What It's Supposed to Do
The idea behind MOTW is actually reasonable. When you
download an executable from the internet and try to run
it, Windows should probably warn you. When you open a
Word document full of macros from an unknown source,
Office should probably block those macros by default. The
MOTW is the mechanism that makes those warnings
possible.
You've seen it in action. That dialog that says "This
file was blocked because it came from the internet"?
That's MOTW. The yellow banner in Word that says
"Protected View: Be careful—files from the Internet
can contain viruses"? Also MOTW. SmartScreen warnings
when you launch a downloaded installer? You guessed
it.
For a typical user who downloads a suspicious attachment
from a phishing email, this is genuinely useful
protection.
Why It's a Nightmare for Developers
Here's where things go sideways. The MOTW system was
designed for the use case of "grandma downloads a virus."
But developers aren't grandma, and our workflows involve
downloading, syncing, and sharing files constantly. And
MOTW does not care about context.
Visual Studio Designer Crashes
This one has bitten me more times than I can count. If a
.resx resource file has MOTW on it, the
Visual Studio Windows Forms designer will refuse to load
it. You don't get a helpful error message—the
designer just crashes, or you get a cryptic exception
about the file being "blocked." I've spent hours
debugging what turned out to be a two-second fix:
right-click, Properties, Unblock.
This happened to me with HTML Helper's
Frame.resx, with NamtiraLib's Test Bed,
and with pretty much every project I've ever cloned from
a repository or restored from a backup.
OneDrive Makes It Worse
This is the truly infuriating part. OneDrive treats
synced files as "from the internet"—because
technically, they are being downloaded from
Microsoft's cloud servers. So every file that syncs down
to your machine gets a fresh Zone.Identifier stream
stamped on it.
Think about what that means. You create a file on your
desktop. It syncs to OneDrive. You open it on your
laptop. OneDrive downloads it and marks it as untrusted.
Your own file. That you created. On
your other computer.
But wait, it gets better. Say you notice the MOTW and
dutifully right-click, Properties, check Unblock, click
Apply. Great, the Zone.Identifier stream is removed. But
the next time OneDrive syncs that file—because you
edited it on another machine, or because OneDrive just
feels like re-syncing it—the MOTW comes right
back.
Build Failures and Cryptic Errors
.NET projects with embedded resources are especially
vulnerable. If any .resx file, any embedded
image, any resource file in the project tree has MOTW,
the build can fail with errors that give you absolutely
no indication that the problem is a security flag. You'll
see messages about files being "inaccessible" or
"corrupted" when they're perfectly fine—just
branded with a scarlet letter from the internet
zone.
NuGet packages, npm modules, anything downloaded by a
package manager—these can all arrive with MOTW.
Most of the time the tooling handles it, but every so
often something slips through and you're left scratching
your head.
The "Unblock" Checkbox That Doesn't Stick
Windows provides a built-in way to remove MOTW:
right-click the file, go to Properties, and check the
"Unblock" checkbox at the bottom of the General tab. In
theory, clicking Apply removes the Zone.Identifier
stream. In practice, this works about 80% of the time.
The other 20%, the checkbox appears to work but the
stream persists, or it gets re-applied almost immediately
by OneDrive or another sync service.
For a single file, this is merely annoying. For a
project with hundreds of files, it's not even a viable
approach.
How to Fix It from Windows
The Manual Way
For individual files, you can still try the Properties
dialog:
- Right-click the file in Explorer
- Select Properties
- On the General tab, look for "Security: This file
came from another computer and might be blocked to
help protect this computer"
- Check the Unblock checkbox
- Click Apply
For multiple files, you can select them all, right-click,
Properties, and unblock them as a batch. But this only
works for files in a single folder; it doesn't recurse
into subfolders.
PowerShell
PowerShell provides the Unblock-File
cmdlet:
Unblock-File -Path "C:\MyProject\SomeFile.resx"
To unblock everything in a folder recursively:
Get-ChildItem -Path "C:\MyProject" -Recurse | Unblock-File
You can also remove the stream directly:
Remove-Item -Path "C:\MyProject\SomeFile.resx" -Stream Zone.Identifier
These work, but they're commands you have to remember to
run every time you sync, clone, or restore files. And if
you forget, you get to play "find the blocked file"
again.
Group Policy
There is a Group Policy setting that can disable MOTW
entirely: User Configuration > Administrative
Templates > Windows Components > Attachment Manager
> Do not preserve zone information in file
attachments. Set it to Enabled, and Windows will stop
applying Zone.Identifier to downloaded files.
But most people don't know this exists, it requires
administrative access, and some organizations' IT
departments would have opinions about disabling it
entirely.
How to Fix It Programmatically
If you're a developer who needs to deal with this in
code, the approach is straightforward: delete the
alternate data stream.
In PowerShell, the recursive approach is the most
practical:
Get-ChildItem -Path "C:\MyProject" -Recurse |
ForEach-Object {
Remove-Item -Path $_.FullName -Stream Zone.Identifier -ErrorAction SilentlyContinue
}
In .NET (C# or VB.NET), there's no built-in API for
alternate data streams, but you can call the Windows API
function DeleteFile with the stream syntax,
or simply shell out to the command line:
System.IO.File.Delete(FilePath & ":Zone.Identifier")
That's not a typo—on NTFS, you can address an
alternate data stream by appending a colon and the stream
name to the file path. The File.Delete
method will happily remove just the stream without
touching the file itself.
To process an entire directory tree:
For Each FilePath As String In System.IO.Directory.GetFiles(
FolderPath, "*", SearchOption.AllDirectories)
Try
System.IO.File.Delete(FilePath & ":Zone.Identifier")
Catch
' File didn't have the stream, or access was denied
End Try
Next
The Nuclear Option
I got so tired of dealing with this that I wrote a tiny
utility called UnblockAll that recursively removes MOTW
from every file in a folder. You point it at your project
root, it strips every Zone.Identifier stream it can find,
and you get back to work. No more designer crashes, no
more mysterious build failures, no more fighting with
OneDrive.
You can download UnblockAll
here (includes a ReadMe). Drop the exe in any folder
and double-click it in File Explorer—it will
unblock every file in that folder and its subfolders. You
can also run it from the command line (though I will never understand this
impulse on the part of new programmers to use the command line. How retro!).
UnblockAll C:\MyProject will target a specific
folder. It requires .NET 10 to be on your system.
In the meantime, that PowerShell one-liner will get you
through the day. But honestly, in 2026, it's absurd that
we still have to deal with this. A security feature that
actively interferes with legitimate development workflows
and treats your own cloud-synced files as hostile isn't
protecting anyone—it's just wasting everyone's
time.