"not a valid Win32 Application" when building on a Windows Server 2008

Viewed 1630

I have the following problem. I have a simple Golang application that I build for each OS and ARCH. Whereby OS I mean:

  • Windows (GOOS=windows)
  • OSX (it is built on OSX machines)

And Arch:

  • 32 (GOARCH=amd64)
  • 64 (GOARCH=386)

Everything works just fine for MAC OS X, Windows Server 2008+. But I encounter a problem when I'm trying to run a compiled application on Windows Server 2008 SP2. I got the following error:

App.exe is not a valid Win32 application

and when trying to run from PowerShell:

The specified executable is not a valid application for this OS platform

My application is almost 1:1 to this

Here is a code if the link wouldn't work in the future:

package main

import (
    "fmt"
    "time"

    "github.com/pion/webrtc/v3"
    "github.com/pion/webrtc/v3/examples/internal/signal"
)

func main() {
    // Everything below is the Pion WebRTC API! Thanks for using it ❤️.

    // Prepare the configuration
    config := webrtc.Configuration{
        ICEServers: []webrtc.ICEServer{
            {
                URLs: []string{"stun:stun.l.google.com:19302"},
            },
        },
    }

    // Create a new RTCPeerConnection
    peerConnection, err := webrtc.NewPeerConnection(config)
    if err != nil {
        panic(err)
    }

    // Set the handler for ICE connection state
    // This will notify you when the peer has connected/disconnected
    peerConnection.OnICEConnectionStateChange(func(connectionState webrtc.ICEConnectionState) {
        fmt.Printf("ICE Connection State has changed: %s\n", connectionState.String())
    })

    // Register data channel creation handling
    peerConnection.OnDataChannel(func(d *webrtc.DataChannel) {
        fmt.Printf("New DataChannel %s %d\n", d.Label(), d.ID())

        // Register channel opening handling
        d.OnOpen(func() {
            fmt.Printf("Data channel '%s'-'%d' open. Random messages will now be sent to any connected DataChannels every 5 seconds\n", d.Label(), d.ID())

            for range time.NewTicker(5 * time.Second).C {
                message := signal.RandSeq(15)
                fmt.Printf("Sending '%s'\n", message)

                // Send the message as text
                sendErr := d.SendText(message)
                if sendErr != nil {
                    panic(sendErr)
                }
            }
        })

        // Register text message handling
        d.OnMessage(func(msg webrtc.DataChannelMessage) {
            fmt.Printf("Message from DataChannel '%s': '%s'\n", d.Label(), string(msg.Data))
        })
    })

    // Wait for the offer to be pasted
    offer := webrtc.SessionDescription{}
    signal.Decode(signal.MustReadStdin(), &offer)

    // Set the remote SessionDescription
    err = peerConnection.SetRemoteDescription(offer)
    if err != nil {
        panic(err)
    }

    // Create an answer
    answer, err := peerConnection.CreateAnswer(nil)
    if err != nil {
        panic(err)
    }

    // Create channel that is blocked until ICE Gathering is complete
    gatherComplete := webrtc.GatheringCompletePromise(peerConnection)

    // Sets the LocalDescription, and starts our UDP listeners
    err = peerConnection.SetLocalDescription(answer)
    if err != nil {
        panic(err)
    }

    // Block until ICE Gathering is complete, disabling trickle ICE
    // we do this because we only can exchange one signaling message
    // in a production application you should exchange ICE Candidates via OnICECandidate
    <-gatherComplete

    // Output the answer in base64 so we can paste it in browser
    fmt.Println(signal.Encode(*peerConnection.LocalDescription()))

    // Block forever
    select {}
}

I'm using GO 1.14 and build it via:

  • go build -ldflags "-s -w" app.go
  • I tried also go build app.go but it changed nothing :(
1 Answers

I believe this is because since Go 1.13 the Windows version specified by internally-linked Windows binaries is now Windows 7:

The Windows version specified by internally-linked Windows binaries is now Windows 7 rather than NT 4.0. This was already the minimum required version for Go, but can affect the behavior of system calls that have a backwards-compatibility mode. These will now behave as documented. Externally-linked binaries (any program using cgo) have always specified a more recent Windows version.

Windows 7 has release version NT 6.1, Windows Server 2008 has release version NT 6.0 (source). So simply Windows Server 2008 does not meet the minimum required Windows version required by the built binaries.

If you need to support Windows Server 2008, try building it with Go 1.12.

Related