go-legacy-win7 is a fork of the Go programming language that maintains support for Windows 7, 8, 8.1, Server 2008 R2, Server 2012, and Server 2012 R2, and restores the deprecated go get behaviour. This project aims to provide a stable Go environment for users who need to support legacy Windows systems or prefer the traditional Go workflow.

-
Windows 7/8/8.1 and Legacy Server Support
While the official Go project dropped support for Windows 7, 8, 8.1, Server 2008 R2, Server 2012, and Server 2012 R2 in Go 1.21, this fork maintains compatibility with all these legacy Windows systems.Tested on Windows 7 RTM (build 7600) — no updates required — through Windows 11 25H2
-
Upstream Code First, Not a Blind Revert
Since1.26.8-1and1.27.1-1, legacy support is no longer restored by reverting upstream changes or freezing old code. Upstream's current implementation is kept, with a fallback beneath it chosen at runtime by what the machine actually supports. Each fallback is built to reproduce upstream's behaviour as closely as the platform allows, so a program behaves the same whether it runs on Windows 7 or Windows 11, and current Windows is unaffected. -
Classic
go getBehaviour
This fork allows for the deprecatedgo getbehaviour whenGO111MODULEis set to "off" or "auto". This means:- In
GOPATH/src,go getandgo installcan operate inGOPATHmode. - Outside of
GOPATH/src, these commands can use module-aware mode when appropriate.
- In
-
Compatibility Notes
Please be aware that some newer Go features may not be fully compatible with legacy Windows systems. We try to maintain as much functionality as possible, but some limitations may exist. If you find one, please report it.
Current release includes the following modifications:
| Change | Patches | Broken by |
|---|---|---|
The linker stamps PE MajorOperatingSystemVersion and MajorSubsystemVersion 6.1, and syscall.GetVersion reports the version RtlGetVersion does rather than the Windows 8 that the compatibility shim reports to such an image. |
0001 | 341b5e2 (Go 1.27) |
The runtime and syscall load system libraries by absolute path where the restricted search flag is not understood. |
0002 | a17d959 (Go 1.21) |
The runtime and crypto/rand fall back to RtlGenRandom where ProcessPrng is absent, which is every Windows before 8. |
0003 | 693def1 (Go 1.22, and 1.21.5 by backport) |
syscall duplicates console handles in StartProcess the way Windows 7 requires. |
0004 | 2d76081 (Go 1.17) 48042aa (Go 1.22) |
os reads directories through FILE_ID_BOTH_DIR_INFO where the newer information classes are unavailable. |
0005 | be0b8e8 (Go 1.22) 2860e01 (Go 1.23) |
os opens the console devices under the names Windows 7 reports as missing. |
0006 | 28b8851 (Go 1.23) bb0c14b (Go 1.25) |
net creates a socket without WSA_FLAG_NO_HANDLE_INHERIT where that flag is rejected, and clears the inherit flag afterwards. |
0007 | 7c1157f (Go 1.22) |
internal/poll keeps files off a completion port they could not leave, with deadlines of their own, and drives a socket that cannot leave one with an event, so os.File.Fd hands back a detached handle wherever the kernel allows it and connections still work where it does not. |
0008 0010 |
8a8f506 (Go 1.25) 6953ef8 (Go 1.25) |
internal/poll no longer hangs on a datagram receive that truncates. |
0009 | 932d0ae (Go 1.21) |
internal/syscall/windows and os open, rename and delete files and directories through fallbacks where the kernel rejects the newer calls. That covers read-only directories that os.RemoveAll left behind, and a file that is deleted, through os.Remove as well, or replaced by a rename gives its name up at once rather than holding it until the last handle closes. |
0011 0012 0013 0014 |
86a1a99 (Go 1.24) 2ffda87 (Go 1.25) b31dc77 (Go 1.26) 6d41809 (Go 1.25) |
-race binaries no longer fail to load for api-ms-win-core-synch-l1-2-0.dll. |
0015 | c3bea70 (Go 1.19) cc82867 (Go 1.21) |
The go command runs GOPATH-mode go get outside a module again. |
9999 | de4d503 (Go 1.22) |
Four test-only changes: one AVX instruction is avoided, and three checks skip where the machine cannot supply what they need. The T sequence touches test files only and changes nothing a program does. |
T0001 T0002 T0003 T0004 |
52fd498 (Go 1.27) 7986e26 (Go 1.23) b691a2e (Go 1.27) bb8f9a6 (Go 1.21) |
Every fallback is coupled with tests, and the fork passes Go's full test suite on Windows 7 x64.
Download builds from GitHub Releases:
- Latest release — current recommended version
- All releases — every published version, including older Go lines
To avoid PATH/GOROOT conflicts and mixed toolchains, uninstall any existing Go installation first.
Windows Installation
- Download the
go-legacy-win7-<version>.windows_<arch>.zipfile. - Extract the ZIP to
C:\(or any preferred location). This will create ago-legacy-win7folder. - Add the following to your system environment variables:
- Add
C:\go-legacy-win7\bin(or your chosen path) to the systemPATH. - Set
GOROOTtoC:\go-legacy-win7(or your chosen path).
- Add
- Add the following to your user environment variables:
- Add
%USERPROFILE%\go\binto the userPATH. - Set
GOPATHto%USERPROFILE%\go.
- Add
macOS and Linux Installation
-
Download the appropriate
go-legacy-win7-<version>.<os>_<arch>.tar.gzfile.- For macOS:
go-legacy-win7-<version>.darwin_<arch>.tar.gz - For Linux:
go-legacy-win7-<version>.linux_<arch>.tar.gz
- For macOS:
-
Extract the archive to
/usr/local:sudo tar -C /usr/local -xzf go-legacy-win7-<version>.<os>_<arch>.tar.gz -
Add the following to your shell configuration file:
- For bash, add to
~/.bash_profileor~/.bashrc - For zsh, add to
~/.zshrc
export GOROOT=/usr/local/go-legacy-win7 export GOPATH=$HOME/go export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
- For bash, add to
-
Apply the changes:
- For bash:
source ~/.bash_profileorsource ~/.bashrc - For zsh:
source ~/.zshrc
Note:
- On macOS Catalina and later, zsh is the default shell.
- On most Linux distributions, bash is the default shell.
- For bash:
After installation, verify the installation by opening a new terminal and running:
go version
To install from source, please follow the steps on the official website.
Is this official Go?
No. It is an independent fork. Bug reports for this fork belong here. Language and spec issues still belong with upstream Go.
Why not just use an old Go release?
Old releases miss years of fixes and language/runtime updates. This fork tracks current Go releases while retaining the legacy Windows and go get support.
Will you drop Windows 7 or raise system requirements?
No. Supporting Windows 7 and later is a standing promise. We aim to keep things working. We do not “fix” what is not broken.
What about security on legacy Windows?
Older Windows already has a large attack surface. Hardening individual legacy APIs here would not make those systems meaningfully safer. We prioritise stable behaviour instead, without weakening what upstream Go already guarantees. Prefer a Windows version Microsoft still supports when you can. This fork exists for cases where you cannot.
Is this safe to use on modern Windows?
Yes. The fork always prefers upstream's implementation and falls back only where the running system cannot provide it, so on current Windows you get exactly the APIs upstream Go uses. Neither side pays for the other. Legacy systems gain support they would otherwise not have, and modern systems give up nothing measurable in return.
Do I need a separate -race build?
No, not anymore. Earlier releases split the build because -race binaries could not start on Windows 7. That gap is closed, so one build now covers every supported Windows version.
Can I mix this with an official Go install?
Avoid it. Uninstall other Go installs first (or keep isolated GOROOT/PATH) so tools do not pick the wrong binary.
Feedback and issue reports are welcome, and we encourage you to open pull requests to contribute to the project. We appreciate your help!
Note that the Go project uses the issue tracker for bug reports and proposals only. See https://go.dev/wiki/Questions for a list of places to ask questions about the Go language.