Go version
go version go1.25.0 windows/amd64
Output of go env in your module/workspace:
set AR=ar
set CC=gcc
set CGO_CFLAGS=-O2 -g
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-O2 -g
set CGO_ENABLED=1
set CGO_FFLAGS=-O2 -g
set CGO_LDFLAGS=-O2 -g
set CXX=g++
set GCCGO=gccgo
set GO111MODULE=on
set GOAMD64=v1
set GOARCH=amd64
set GOAUTH=netrc
set GOBIN=
set GOCACHE=C:\Users\cj\AppData\Local\go-build
set GOCACHEPROG=
set GODEBUG=
set GOENV=C:\Users\cj\AppData\Roaming\go\env
set GOEXE=.exe
set GOEXPERIMENT=
set GOFIPS140=off
set GOFLAGS=
set GOGCCFLAGS=-m64 -mthreads -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=C:\Users\cj\AppData\Local\Temp\go-build3808498674=/tmp/go-build -gno-record-gcc-switches
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOINSECURE=
set GOMODCACHE=C:\Users\cj\go\pkg\mod
set GOOS=windows
set GOPATH=C:\Users\cj\go
set GOPROXY=https://proxy.golang.org,direct
set GOROOT=C:/Program Files/Go
set GOSUMDB=sum.golang.org
set GOTELEMETRY=local
set GOTELEMETRYDIR=C:\Users\cj\AppData\Roaming\go\telemetry
set GOTMPDIR=
set GOTOOLCHAIN=auto
set GOTOOLDIR=C:\Program Files\Go\pkg\tool\windows_amd64
set GOVCS=
set GOVERSION=go1.25.0
set GOWORK=
set PKG_CONFIG=pkg-config
What did you do?
As of Go 1.25, a simple app which uses CGO will fail to run on Windows with the error failed to run: The specified executable is not a valid application for this OS
Example code: https://go.dev/play/p/YKuBXwCGWAd
This same code will run successfully when built with GOEXPERIMENT=nodwarf5 OR stripping debug info -ldflags="-s -w"
dumpbin.exe output shows sections being placed at virtual addresses outside of the normal Windows PE address space.
With DWARF5 enabled:
SECTION HEADER #1
/4 name (.debug_rnglists)
1B7D1 virtual size
C0000000 virtual address (0000000200000000 to 000000020001B7D0)
1B800 size of raw data
548 file pointer to raw data (00000548 to 0001BD47)
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
42100040 flags
Initialized Data
RESERVED - UNKNOWN
Discardable
Read Only
With GOEXPERIMENT=nodwarf5:
SECTION HEADER #1
.text name
B0720 virtual size
1000 virtual address (0000000140001000 to 00000001400B171F)
B0800 size of raw data
600 file pointer to raw data (00000600 to 000B0DFF)
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
60600060 flags
Code
Initialized Data
RESERVED - UNKNOWN
RESERVED - UNKNOWN
Execute Read
What did you see happen?
Program 'main.exe' failed to run: The specified executable is not a valid application for this OS platform.At line:1
char:1
What did you expect to see?
Message: Hello from C!
Comment From: qmuntal
Thanks for reporting this isssue. This issue has not been triggered in CI, nor I can reproduce it locally. Thid makes me think that is dependant on a specific C toolchain. Which Mingw-w64 are you using? From where did you download it?
Comment From: seejdev
Thanks for your help. It was downloaded from https://jmeubank.github.io/tdm-gcc/download/
The installer says the mingw64-runtime version is v8-git2021050601-gcc10-tdm64-1
gcc -v
Using built-in specs.
COLLECT_GCC=C:\TDM-GCC-64\bin\gcc.exe
COLLECT_LTO_WRAPPER=C:/TDM-GCC-64/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.0/lto-wrapper.exe
Target: x86_64-w64-mingw32
Configured with: ../../../src/gcc-git-10.3.0/configure --build=x86_64-w64-mingw32 --enable-targets=all --enable-languages=ada,c,c++,fortran,jit,lto,objc,obj-c++ --enable-libgomp --enable-lto --enable-graphite --enable-cxx-flags=-DWINPTHREAD_STATIC --disable-build-with-cxx --disable-build-poststage1-with-cxx --enable-libstdcxx-debug --enable-threads=posix --enable-versio
n-specific-runtime-libs --enable-fully-dynamic-string --enable-libstdcxx-filesystem-ts=yes --disable-libstdcxx-pch --enable-libstdcxx-threads --enable-libstdcxx-time=yes --enable-mingw-wildcard --with-gnu-ld --disable-werror --enable-nls --disable-win32-registry --enable-large-address-aware --disable-rpath --disable-symvers --prefix=/mingw64tdm --with-local-prefix=/mingw64tdm --with-pkgversion=tdm64-1 --with-bugurl=https://github.com/jmeubank/tdm-gcc/issues
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 10.3.0 (tdm64-1)
Comment From: prattmic
It seems strange that the binary appears to have a dwarf section first, rather than the .text section.
Have you tried any other C toolchain versions?
Comment From: dev-abir
I can reproduce this issue on Go 1.25.0 (windows/amd64) and it does not occur on Go 1.24.6.
It doesn't appear to be a C toolchain issue. I am using an older version of MinGW:
gcc -v
Using built-in specs.
COLLECT_GCC=C:\Program Files\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\bin\gcc.exe
COLLECT_LTO_WRAPPER=C:/Program\ Files/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/bin/../libexec/gcc/x86_64-w64-mingw32/8.1.0/lto-wrapper.exe
Target: x86_64-w64-mingw32
Configured with: ../../../src/gcc-8.1.0/configure --host=x86_64-w64-mingw32 --build=x86_64-w64-mingw32 --target=x86_64-w64-mingw32 --prefix=/mingw64 --with-sysroot=/c/mingw810/x86_64-810-posix-seh-rt_v6-rev0/mingw64 --enable-shared --enable-static --disable-multilib --enable-languages=c,c++,fortran,lto --enable-libstdcxx-time=yes --enable-threads=posix --enable-libgomp --enable-libatomic --enable-lto --enable-graphite --enable-checking=release --enable-fully-dynamic-string --enable-version-specific-runtime-libs --disable-libstdcxx-pch --disable-libstdcxx-debug --enable-bootstrap --disable-rpath --disable-win32-registry --disable-nls --disable-werror --disable-symvers --with-gnu-as --with-gnu-ld --with-arch=nocona --with-tune=core2 --with-libiconv --with-system-zlib --with-gmp=/c/mingw810/prerequisites/x86_64-w64-mingw32-static --with-mpfr=/c/mingw810/prerequisites/x86_64-w64-mingw32-static --with-mpc=/c/mingw810/prerequisites/x86_64-w64-mingw32-static --with-isl=/c/mingw810/prerequisites/x86_64-w64-mingw32-static --with-pkgversion='x86_64-posix-seh-rev0, Built by MinGW-W64 project' --with-bugurl=https://sourceforge.net/projects/mingw-w64 CFLAGS='-O2 -pipe -fno-ident -I/c/mingw810/x86_64-810-posix-seh-rt_v6-rev0/mingw64/opt/include -I/c/mingw810/prerequisites/x86_64-zlib-static/include -I/c/mingw810/prerequisites/x86_64-w64-mingw32-static/include' CXXFLAGS='-O2 -pipe -fno-ident -I/c/mingw810/x86_64-810-posix-seh-rt_v6-rev0/mingw64/opt/include -I/c/mingw810/prerequisites/x86_64-zlib-static/include -I/c/mingw810/prerequisites/x86_64-w64-mingw32-static/include' CPPFLAGS=' -I/c/mingw810/x86_64-810-posix-seh-rt_v6-rev0/mingw64/opt/include -I/c/mingw810/prerequisites/x86_64-zlib-static/include -I/c/mingw810/prerequisites/x86_64-w64-mingw32-static/include' LDFLAGS='-pipe -fno-ident -L/c/mingw810/x86_64-810-posix-seh-rt_v6-rev0/mingw64/opt/lib -L/c/mingw810/prerequisites/x86_64-zlib-static/lib -L/c/mingw810/prerequisites/x86_64-w64-mingw32-static/lib '
Thread model: posix
gcc version 8.1.0 (x86_64-posix-seh-rev0, Built by MinGW-W64 project)
Comment From: michaelquigley
I have also been able to reproduce this using Go 1.25.0, and it does not occur on Go 1.24.6. I am also using TDM-GCC (which is a very tidy Windows-based installation that typically works very well for CGO builds).
Setting GOEXPERIMENT=nodwarf5 does result in a working build.
Comment From: prattmic
cc @golang/compiler @golang/windows @thanm
Comment From: thanm
Thanks for the report.
@seejdev it would be helpful to understand whether this problem happens only with external linking or also with internal linking (in some other reports it sounds like the problems is with internal linking).
Would you kindly try your example with "go build -ldflags=-linkmode=internal" to see whether the resulting executable still works? Thanks.
Comment From: syllith
I can confirm I’m hitting this same problem on Windows with Go 1.25.0. It does not happen on 1.24.6.
In my case the binaries built with the external linker fail immediately with the “This app can’t run on your PC” dialog. Inspection shows that SizeOfHeaders is not rounded to a multiple of FileAlignment (1352 vs 512), and the first sections have PointerToRawData values misaligned to 512. There are also section names like /4, /20, /36 at RVA 0xC0000000 that look like COFF long-name placeholders, which should never appear in a final PE. With headers/sections in this state the Windows loader refuses to start the program.
Workarounds:
Using stripped debug info works: go build -ldflags="-H=windowsgui -w -s" .
So for me it seems to be the external linker + DWARF5 debug emission that triggers malformed PE output. Removing debug info avoids it, which matches what others here have seen.
[Edited by thanm on 6 Sep 2025 to correct typos on internal vs external linking]
Comment From: thanm
OK, for the folks who are running into this bug, I am assuming that the C linker you're using (from the C compiler toolchain) is built from binutils -- would you kindly check to see which version of binutils is being used for your particular toolchain? I assume this can be done with "ld --version" or equivalent.
I looked at the binutils sources and it appears that support for DWARF 5 was added in this commit: ba6eb62ff0ea9843a018cfd7cd06777bd66ae0a0, which was first released in binutils version 2.37. Binutils 2.37 was put out in July of 2021 so about four years ago.
If you are using a linker built off an older version of binutils, then most likely what's happening is that the linker sees a ".debug_rnglists" section (DWARF-5 specific) and assumes that it is a loadable data section (incorrect) as opposed to a non-loadable data section.
Thanks.
Comment From: syllith
GNU ld (GNU Binutils) 2.36.1
I'm also using TDM GCC, which looks like the latest release was in 2021. Their page says:
TDM-GCC 10.3.0 is now available, along with GDB 10.2, binutils 2.36.1, and new versions of the MinGW.org and MinGW-w64 runtime distributions. Thanks for your patience!
Comment From: thanm
OK, then that confirms it. The linker in your C compiler doesn't understand DWARF 5 -- hence the confusion with the sections winding up loadable as opposed to non-loadable. Thanks.
Comment From: dev-abir
Upgraded my toolchain and this is fixed:
Using built-in specs.
COLLECT_GCC=C:\mingw64\bin\gcc.exe
COLLECT_LTO_WRAPPER=C:/mingw64/bin/../libexec/gcc/x86_64-w64-mingw32/15.2.0/lto-wrapper.exe
OFFLOAD_TARGET_NAMES=nvptx-none
Target: x86_64-w64-mingw32
Configured with: ../configure --prefix=/R/winlibs_staging_msvcrt64/inst_gcc-15.2.0/share/gcc --build=x86_64-w64-mingw32 --host=x86_64-w64-mingw32 --enable-offload-targets=nvptx-none --with-pkgversion='MinGW-W64 x86_64-msvcrt-posix-seh, built by Brecht Sanders, r1' --with-tune=generic --enable-checking=release --enable-threads=posix --disable-sjlj-exceptions --disable-libunwind-exceptions --disable-serial-configure --disable-bootstrap --enable-host-shared --enable-plugin --disable-default-ssp --disable-rpath --disable-libstdcxx-debug --disable-version-specific-runtime-libs --disable-symvers --enable-languages=c,c++,fortran,lto,objc,obj-c++ --disable-gold --disable-nls --disable-stage1-checking --disable-win32-registry --disable-multilib --enable-ld --enable-libquadmath --enable-libada --enable-libssp --enable-libstdcxx --enable-lto --enable-fully-dynamic-string --enable-libgomp --enable-graphite --enable-mingw-wildcard --enable-libstdcxx-time --enable-libstdcxx-pch --with-mpc=/c/Prog/winlibs_staging_msvcrt/custombuilt64 --with-mpfr=/c/Prog/winlibs_staging_msvcrt/custombuilt64 --with-gmp=/c/Prog/winlibs_staging_msvcrt/custombuilt64 --with-isl=/c/Prog/winlibs_staging_msvcrt/custombuilt64 --disable-libstdcxx-backtrace --enable-install-libiberty --enable-__cxa_atexit --without-included-gettext --with-diagnostics-color=auto --enable-clocale=generic --enable-libgdiagnostics --with-libiconv --with-system-zlib --with-build-sysroot=/R/winlibs_staging_msvcrt64/gcc-15.2.0/build_mingw/mingw-w64 CFLAGS='-I/c/Prog/winlibs_staging_msvcrt/custombuilt64/include/libdl-win32 -march=nocona -msahf -mtune=generic -O2 -Wno-error=format' CXXFLAGS='-Wno-int-conversion -march=nocona -msahf -mtune=generic -O2' LDFLAGS='-pthread -Wl,--no-insert-timestamp -Wl,--dynamicbase -Wl,--high-entropy-va -Wl,--nxcompat -Wl,--tsaware' LD=/c/Prog/winlibs_staging_msvcrt/custombuilt64/share/binutils/bin/ld.exe
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 15.2.0 (MinGW-W64 x86_64-msvcrt-posix-seh, built by Brecht Sanders, r1)
Also, the sections now seem to be aligned to FileAlignment.
Comment From: thrasher-
Can also confirm that after experiencing this issue, updating the gcc toolchain resolved this issue
Comment From: michaelquigley
Updating my toolchain also fixed the issue:
$ ld --version
GNU ld (Binutils for MinGW-W64 x86_64, built by Brecht Sanders, r1) 2.45
Copyright (C) 2025 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or (at your option) a later version.
This program has absolutely no warranty.
Comment From: seejdev
@thanm Thanks for looking into this. I tried your suggestion and confirmed the resulting executable does work, even with the older TDM-GCC toolchain, if I build with go build -ldflags=-linkmode=internal
I also confirmed like others have, swapping TDM-GCC to the latest MinGW-W64 15.2 version resolves the issue and I can build a good binary with Go 1.25 and without disabling DWARF 5 generation.
Comment From: thanm
Thanks @seejdev .
One more thing that might be helpful is if you could try doing a C build with your old TDM-GCC 10.x compiler and see whether that version of GCC accepts the -gdwarf-5 command line option. If this option is rejected, then one thing we could conceivably do is have the linker test for it (when using CGO on Windows) and then fail the build (with a suitably descriptive error message) if it is not supported. This would be (at least in my mind) preferable to having the link succeed but produce a non-working binary.
Comment From: nixomose
One more thing that might be helpful is if you could try doing a C build with your old TDM-GCC 10.x compiler and see whether that version of GCC accepts the
-gdwarf-5command line option. If this option is rejected, then one thing we could conceivably do is have the linker test for it (when using CGO on Windows) and then fail the build (with a suitably descriptive error message) if it is not supported. This would be (at least in my mind) preferable to having the link succeed but produce a non-working binary.
Hi, I work with seejdev and I'm taking a look at this problem too, just getting up to speed. I tried what you said: and the tdm-gcc compiler (10.3.0)
C:\TDM-GCC-64\bin\test>\TDM-GCC-64\bin\gcc.exe --version gcc.exe (tdm64-1) 10.3.0
seems to honor the -gdwarf-5 flag, with a simple test program, there was a small change in the binary output size so it must be writing different debug information...
C:\TDM-GCC-64\bin\test>\TDM-GCC-64\bin\gcc.exe test.c
C:\TDM-GCC-64\bin\test>dir /od
Volume in drive C is windowsdriveclabel
Volume Serial Number is A861-DFB7
Directory of C:\TDM-GCC-64\bin\test
09/04/2025 02:04 PM 99 test.c
09/04/2025 02:07 PM 367,349 a.exe
2 File(s) 367,448 bytes
2 Dir(s) 11,826,728,960 bytes free
C:\TDM-GCC-64\bin\test>\TDM-GCC-64\bin\gcc.exe -gdwarf-5 test.c
C:\TDM-GCC-64\bin\test>dir /od
Volume in drive C is windowsdriveclabel
Volume Serial Number is A861-DFB7
Directory of C:\TDM-GCC-64\bin\test
09/04/2025 02:04 PM 99 test.c
09/04/2025 02:07 PM 368,589 a.exe
2 File(s) 368,688 bytes
2 Dir(s) 11,826,728,960 bytes free
So no, it does not appear that the -gdwarf-5 option is rejected.
If that's any help.
Comment From: thanm
@nixomose yes thank you, that is helpful.
Given the circumstances it doesn't look as though it's practical to try to implement a compiler check as I had envisioned. I think the path forward here is just to make sure that folks are using an up to date C compiler toolchain.
Comment From: prattmic
It sounds like the preferred fix here is an update to https://go.dev/wiki/MinimumRequirements to clarify requirements?
Comment From: thanm
It sounds like the preferred fix here is an update to https://go.dev/wiki/MinimumRequirements to clarify requirements?
That seems like a good idea. I'll send a CL.
Comment From: gopherbot
Change https://go.dev/cl/701475 mentions this issue: MinimumRequirements.md: add note on minimum GCC version for CGO on Windows