53

Every time I am running Go applications on MacOs with this command:

go run main.go

I get this pop up message:

Do you want the application "main" to accept incoming network connections?

I added Go and all main executable files to Firewall Exceptions but I am still getting this pop ups. I am running out of ideas. Please can anyone help me to get rid of those pop ups? At this point I have no idea if the problem is related to Golang or MacOs.

4
  • 1
    when you develop servers on a linux laptop/desktop you get no such nonsense ;-) Commented Mar 14 at 22:23
  • If only employers were happy for people to work on Linux machines. It is always either a MacBook or a Windows laptop :D Commented Mar 17 at 17:42
  • At least on a Windows laptop, you can install Ubuntu on WSL2... what do I do on macOS? Just suffer!
    – ADTC
    Commented May 30 at 15:52
  • You can run Ubuntu as a VM on Mac too via Paralles or VirtualBox etc Commented Jun 7 at 10:38

3 Answers 3

60

You can avoid this pop-up when running local tests if you specify the host portion of the address that will be listened to to be "localhost" or "127.0.0.1". Many programs let you set the address through the command line or an environment variable and many of those programs will default to passing no host to the listen command. With no host specified, Go will listen on 0.0.0.0 and macOS will want to warn you about that. When Go opens ports on the localhost, macOS doesn't warn - at least not in my cases.

For example, instead of:

r := gin.Default()
r.Run()

you can write:

r := gin.Default()
r.Run("localhost:8080")
2
  • Didn't work for me. Server refuses to run if localhost or 127.0.0.1 is put in the front of port.
    – ADTC
    Commented May 30 at 15:54
  • Update: I'm on macOS and I was using :80, and apparently non-sudoers are denied from binding to ports below 1024. You have to either run the server with sudo or change to a port >= 1024.
    – ADTC
    Commented May 30 at 16:23
19

Thanks to the answer by @WeakPointer above, I figured all we need to do in our code is to replace:

http.ListenAndServe(":8080", nil)

by:

http.ListenAndServe("localhost:8080", nil)

or if using a library like gin-gonic, replace:

r.Run()

by:

r.Run("localhost:8080")
2
  • This didn't work for me. Server refuses to run if localhost or 127.0.0.1 is put in the front of port.
    – ADTC
    Commented May 30 at 15:54
  • Update: I'm on macOS and I was using :80, and apparently non-sudoers are denied from binding to ports below 1024. You have to either run the server with sudo or change to a port >= 1024.
    – ADTC
    Commented May 30 at 16:22
14

This is normal behaviour.

Each time you run go run main.go a new executable file is being created. This executable file is unique and unrecognised by macOS's security checks. Thus macOS asks, every time, for you to confirm if the new executable can have network access.

Build and Sign

To avoid the warning, you need to build the executable file once and codesign it. You can build the executable file using the command:

go build -o mycmd main.go

The resulting executable called mycmd can be run using:

./mycmd

To ad-hoc codesign this executable use:

codesign -s - mycmd

This will cause macOS to trust this build of mycmd on your Mac. The first time it is run, you will be asked for network access. Subsequent runs will not require network checks.

6
  • thanks, would I have to repeat that each time I change the code? Commented Jun 12, 2020 at 13:17
  • 1
    Yes, each time you recompile the code you will need to codesign and grant the process network access. You might want to consider a small makefile or shell script to combine the go build… and codesign… commands. Commented Jun 12, 2020 at 15:00
  • Clicking "Allow" seems easier... Commented Jun 24, 2021 at 22:36
  • @user3621156 selecting Allow each time can affect the executable's behaviour. Servers that require network access are blocked and may fail or time out before the user can respond. Pre-signing the executable avoids this problem. Commented Jun 25, 2021 at 9:16
  • This is so silly. Yes, if we're doing a production deployment, it makes sense to codesign the executable. But when we're developing, we change the code very frequently, testing, changing, testing, changing again, every few seconds. It would be absurd if we had to build, generate, sign and run a new executable for every little code change we make before we can test it. The correct answer for a development environment is to just "localhost:8080" which makes the warning go away. The correct answer for a production environment is signing the executable.
    – ADTC
    Commented May 30 at 16:29

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .