Go gophergo-legacy-win7Go for Windows 7 and later

Versions

The Go Programming Language

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.

Gopher image Gopher image by Renee French, licensed under Creative Commons 4.0 Attribution licence.

Differences from Upstream Go

  1. 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 (build 7600) — no updates required — through Windows 11 26H2 (build 26300)

  2. Upstream Code First, Not a Blind Revert
    Legacy support is not 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.

  3. Classic go get Behaviour
    This fork allows for the deprecated go get behaviour when GO111MODULE is set to "off" or "auto". This means:

    • In GOPATH/src, go get and go install can operate in GOPATH mode.
    • Outside of GOPATH/src, these commands can use module-aware mode when appropriate.
  4. 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.

Changes in Each Release

Current release includes the following modifications. The last column names the upstream change each patch works around and the Go release it shipped in, or the kernel where there is none. The T patches touch tests only.

Loader and startup

What it fixes Patch Upstream change
Binaries built by stock Go 1.27 do not start on Windows 7, 8 or 8.1. Upstream stamps a Windows 10 minimum version into every PE image. The fork stamps 6.1, and syscall.GetVersion reads the true version so that the compatibility shim cannot report Windows 8 to it. 0001 341b5e2 (Go 1.27)
Every program dies at startup on Windows 7 without KB2533623. The runtime and syscall load system DLLs with a search flag that update introduced. Where the flag is rejected they load the file by its full path in the system directory. 0002 a17d959 (Go 1.21)
Every program dies at startup on Windows 7, which has no ProcessPrng. The runtime and crypto/rand fall back to RtlGenRandom where it is missing. 0003 693def1 (Go 1.22, and 1.21.5 by backport)

Processes and consoles

What it fixes Patch Upstream change
Starting a child process from a console fails on Windows 7, the go command included. Windows 7 console handles are not real handles. StartProcess treats them as Go 1.21 did. 0004 2d76081 (Go 1.17)
48042aa (Go 1.22)
Opening or stating CON, CONIN$ or CONOUT$ fails on Windows 7. The \\.\ names reach the console only from Windows 8. os retries with the bare names. 0006 28b8851 (Go 1.23)
bb0c14b (Go 1.25)

Network and the poller

What it fixes Patch Upstream change
Every socket creation fails on Windows 7 (build 7600). WSA_FLAG_NO_HANDLE_INHERIT needs Service Pack 1. net retries without it and clears inheritance afterwards. 0007 7c1157f (Go 1.22)
File on a connection or listener fails before Windows 8.1. Nothing before 8.1 can take a handle off a completion port. The handle is left where it is and still works, and Close still ends a pending read on it. 0008 8a8f506 (Go 1.25)
6953ef8 (Go 1.25)
A UDP read into a buffer too small for a datagram already queued hangs forever on Windows 7. Datagram sockets no longer skip the completion packet there. 0009 932d0ae (Go 1.21)
os.File.Fd cannot hand back a detached handle before Windows 8.1. Files and pipes are kept off the runtime's completion port there, with deadlines of their own, so Fd returns a detached handle. 0010 8a8f506 (Go 1.25)
d889729 (Go 1.28, and 1.26.9 and 1.27.2 by backport)
Every listener in the process stops accepting on Windows 8 and Server 2012 while a thread reads a pipe. The kernel holds an AcceptEx completion until the posting thread leaves synchronous I/O. AcceptEx is posted from a thread that never does. 0018 Connect #760161 (Windows 8)
Kernel

Files

What it fixes Patch Upstream change
Listing a directory fails on Windows 7 on FAT32, exFAT and network shares. The newer directory information class arrived in Windows 8. os reads with the older one where the kernel rejects the new. 0005 be0b8e8 (Go 1.22)
2860e01 (Go 1.23)
os.RemoveAll leaves a read-only directory behind before Windows 10 1809. The read-only attribute is cleared on a directory as it is on a file. 0011 b31dc77 (Go 1.26)
6d41809 (Go 1.25)
A deleted file keeps its name while another handle holds it, where the kernel has no POSIX delete. A held file is moved aside before it is marked, so the name is free at once, through os.Remove too. 0012 b31dc77 (Go 1.26)
Deleting a program right after it exits fails on Windows 8 and 8.1. The kernel keeps the image mapped for a moment after Wait returns. The delete waits that out. 0013 f0894a0 (Go 1.22)
os.RemoveAll finds a directory not empty while an entry already marked for deletion is on its way out. The delete waits for the name to go. 0014 b31dc77 (Go 1.26)
Kernel
Renaming onto a link or a held file fails where the kernel has no POSIX rename. The target is moved aside, the rename retried, and the copy deleted. 0015 2ffda87 (Go 1.25)
A junction or directory symlink to a file opens on Windows 7, 8 and 8.1 where Windows 10 refuses it. Links are held to their type on every Windows, so a program gets the same answer everywhere. 0016 b19851b (Go 1.28, and 1.26.9 and 1.27.2 by backport)
Kernel

Race detector

What it fixes Patch Upstream change
A -race binary does not start on Windows 7. The race runtime's address wait functions are defined by the fork and emulated where the kernel lacks them, and the Windows 8 import library is no longer linked. 0017 c3bea70 (Go 1.19)
cc82867 (Go 1.21)

The go command

What it fixes Patch Upstream change
go get in GOPATH mode is gone since Go 1.22. Restored, so GO111MODULE=off go get fetches into GOPATH/src and installs again. 9999 de4d503 (Go 1.22)

Tests only

What it fixes Patch Upstream change
A cgo callback test faults on Windows 7 (build 7600). It clobbers a register with an AVX instruction, which Windows 7 enables only from Service Pack 1. SSE2 does the same job. T0001 52fd498 (Go 1.27)
The VHD tests pass on Windows 7 without testing anything. The Hyper-V cmdlets they need arrived with Windows 8. They skip where the cmdlets are missing. T0002 7986e26 (Go 1.23)
A live TLS resumption test fails where the root store lacks the server's root. It skips when no dial verifies. T0003 b691a2e (Go 1.27, and 1.26.0 by backport)
The system certificate verification tests fail where the root store lacks GTS Root R1. Those cases skip. T0004 bb8f9a6 (Go 1.21)

Test Results

Every fallback is coupled with tests, and the fork passes Go's test suite on each system below.

System Version Toolchain Go test suite
Windows 7 32-bit 6.1.7600 windows_386 ✅ Passed
Windows 7 64-bit 6.1.7600 windows_amd64 ✅ Passed
Windows 8 64-bit 6.2.9200 windows_amd64 ✅ Passed
Windows 8.1 64-bit 6.3.9600 windows_amd64 ✅ Passed
Windows 10 32-bit 10.0.19045 windows_386 ✅ Passed
Windows 11 64-bit 10.0.26300 windows_amd64 ✅ Passed

On Windows 10 and 11 the fork matches stock Go.

32-bit builds are tested only on Windows 7 and 10. They behave the same as their 64-bit siblings on the same kernel.

Download and Install

Binary Distributions

Latest release of the Go 1.27 line   Latest release of the Go 1.26 line

Release archives do not include the tests and scripts. Clone the repo if you want to run them.

Before you begin

To avoid PATH/GOROOT conflicts and mixed toolchains, uninstall any existing Go installation first.

Windows Installation
  1. Download the go-legacy-win7-<version>.windows_<arch>.zip file.
  2. Extract the ZIP to C:\ (or any preferred location). This will create a go-legacy-win7 folder.
  3. Add the following to your system environment variables:
    • Add C:\go-legacy-win7\bin (or your chosen path) to the system PATH.
    • Set GOROOT to C:\go-legacy-win7 (or your chosen path).
  4. Add the following to your user environment variables:
    • Add %USERPROFILE%\go\bin to the user PATH.
    • Set GOPATH to %USERPROFILE%\go.
macOS and Linux Installation
  1. Download the appropriate go-legacy-win7-<version>.<os>_<arch>.tar.gz file.

    • For macOS: go-legacy-win7-<version>.darwin_<arch>.tar.gz
    • For Linux: go-legacy-win7-<version>.linux_<arch>.tar.gz
  2. Extract the archive to /usr/local:

    sudo tar -C /usr/local -xzf go-legacy-win7-<version>.<os>_<arch>.tar.gz
    
  3. Add the following to your shell configuration file:

    • For bash, add to ~/.bash_profile or ~/.bashrc
    • For zsh, add to ~/.zshrc
    export GOROOT=/usr/local/go-legacy-win7
    export GOPATH=$HOME/go
    export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
    
  4. Apply the changes:

    • For bash: source ~/.bash_profile or source ~/.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.

After installation, verify the installation by opening a new terminal and running:

go version

Install From Source

To install from source, please follow the steps on the official website.

FAQ

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.

Contributing

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.