Context: Why Setting Up Go Correctly from the Start Matters
The first time I installed Go on Fedora, I just ran sudo dnf install golang and started coding. Everything seemed fine until I needed to build a binary requiring Go 1.22+, while the Fedora repo was a few versions behind. Then the VS Code environment went sideways — the extension couldn’t find GOPATH, the debugger refused to work, and gopls kept crashing. I spent an entire evening tracking down the cause.
I’ve been using Fedora as my main development machine for two years and I’m quite happy with how fast packages get updated — but with Go, installing via DNF doesn’t always give you the latest version. A gap of one or two versions might sound minor, but Go releases on a six-month cycle and each version usually brings meaningful performance improvements and new syntax. This guide walks through the proper setup so you never experience that “why won’t this build” feeling at 2 AM again.
The Problem with Installing via DNF
The Fedora repo typically lags behind the official Go release by one or two versions. If your project requires Go 1.23 but DNF only has 1.21, you’ll hit build errors with no clear explanation. On top of that, the directory structure from a DNF install sometimes doesn’t match what the VS Code extension expects — GOROOT ends up pointing to the wrong path, and the extension struggles to locate the binaries.
Installing the Official Go SDK from golang.org
Step 1: Download the Latest Go Version
Visit go.dev/dl to grab the latest download link. Or use the command below to check the current stable version:
# Check the latest stable version
curl -s https://go.dev/VERSION?m=text
# Download — replace VERSION with the actual version (e.g., go1.23.5)
wget https://go.dev/dl/go1.23.5.linux-amd64.tar.gz
Step 2: Install to /usr/local
# Remove any existing Go installation (important — skipping this causes conflicts)
sudo rm -rf /usr/local/go
# Extract to /usr/local
sudo tar -C /usr/local -xzf go1.23.5.linux-amd64.tar.gz
# Verify the directory exists
ls /usr/local/go/bin/
# Output: go gofmt
Step 3: Configure PATH in Your Shell Profile
Append the following to ~/.bashrc (or ~/.zshrc if you use zsh):
cat >> ~/.bashrc << 'EOF'
export GOROOT=/usr/local/go
export GOPATH=$HOME/go
export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
EOF
# Reload immediately
source ~/.bashrc
# Verify
go version
# Output: go version go1.23.5 linux/amd64
If you still see command not found, check that PATH looks correct:
echo $PATH | tr ':' '\n' | grep go
A common gotcha: if you’re SSH-ing into the machine via a login shell, add the exports to ~/.bash_profile instead of ~/.bashrc — the two files are loaded in different contexts.
Configuring VS Code for Go Development
Installing the Official Go Extension
Open VS Code, go to Extensions (Ctrl+Shift+X), and search for “Go” by publisher “Go Team at Google”. This is the official extension — don’t accidentally install one of the similarly-named forks.
After installing, open any .go file. VS Code will prompt you to install additional Go tools. Click Install All — this includes gopls (the language server), dlv (the Delve debugger), staticcheck, and goimports.
# Install manually via terminal if the popup doesn't appear
go install golang.org/x/tools/gopls@latest
go install github.com/go-delve/delve/cmd/dlv@latest
go install honnef.co/go/tools/cmd/staticcheck@latest
go install golang.org/x/tools/cmd/goimports@latest
Configuring settings.json for VS Code
Open VS Code settings (Ctrl+,), switch to JSON view (icon in the top-right corner), and add the following configuration:
{
"go.goroot": "/usr/local/go",
"go.gopath": "/home/YOUR_USERNAME/go",
"go.toolsManagement.autoUpdate": true,
"go.lintTool": "staticcheck",
"go.formatTool": "goimports",
"go.useLanguageServer": true,
"[go]": {
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.organizeImports": "explicit"
}
}
}
Replace YOUR_USERNAME with your actual username (run whoami to find it). After saving, fully restart VS Code — just reloading the window isn’t enough; gopls needs a clean restart to pick up the correct GOROOT.
Creating Your First Go Project to Verify the Setup
# Create project directory
mkdir -p ~/projects/hello-go && cd ~/projects/hello-go
# Initialize Go module
go mod init hello-go
Create a main.go file:
package main
import (
"fmt"
"runtime"
)
func main() {
fmt.Printf("Hello from Go %s!\n", runtime.Version())
fmt.Printf("OS: %s, Arch: %s\n", runtime.GOOS, runtime.GOARCH)
}
# Run it
go run main.go
# Output:
# Hello from Go go1.23.5!
# OS: linux, Arch: amd64
Setting Up Debugging with Delve in VS Code
Create a .vscode/launch.json file in your project directory:
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug Go App",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}",
"env": {},
"args": []
}
]
}
Set a breakpoint by clicking in the left gutter next to a line of code, then press F5 to start a debug session. If Delve reports a permission error related to ptrace, that’s a Fedora-specific issue caused by kernel security hardening — not a misconfiguration:
# Temporary fix for ptrace error (resets after reboot)
echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope
# Permanent fix
sudo tee /etc/sysctl.d/10-ptrace.conf << 'EOF'
kernel.yama.ptrace_scope = 0
EOF
# Apply immediately without rebooting
sudo sysctl --system
Verifying and Monitoring Your Go Environment
Verifying the Full Installation
# Check Go environment — key values to verify
go env GOROOT GOPATH GOMODCACHE GOPROXY
# Expected output:
# GOROOT=/usr/local/go
# GOPATH=/home/username/go
# GOMODCACHE=/home/username/go/pkg/mod
# GOPROXY=https://proxy.golang.org,direct
# Check installed tools
which gopls && gopls version
which dlv && dlv version
which staticcheck && staticcheck --version
Running Tests to Confirm Everything Works
# Create a test file in the hello-go project
cat > main_test.go << 'EOF'
package main
import "testing"
func TestVersion(t *testing.T) {
got := "hello-go"
want := "hello-go"
if got != want {
t.Errorf("got %q, want %q", got, want)
}
}
EOF
# Run tests
go test -v ./...
# Output:
# --- PASS: TestVersion (0.00s)
# PASS
Script to Update Go When a New Version Releases
The nice thing about installing this way is that updates are straightforward — no DNF conflicts to worry about:
#!/bin/bash
# Save as ~/bin/update-go.sh
NEW_VERSION="go1.24.0" # Replace with the target version
wget https://go.dev/dl/${NEW_VERSION}.linux-amd64.tar.gz
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf ${NEW_VERSION}.linux-amd64.tar.gz
rm ${NEW_VERSION}.linux-amd64.tar.gz
go version
Common Errors and Quick Fixes
- gopls not recognizing GOROOT: Fully restart VS Code after editing settings.json — reloading the window isn’t sufficient.
- go: command not found after adding PATH: Run
source ~/.bashrcor open a new terminal. If using a login shell over SSH, add the exports to~/.bash_profileinstead. - Delve crashing with “operation not permitted”: Fix
ptrace_scopeas shown above — very common on Fedora due to default kernel hardening. - VS Code not formatting code on save: Reinstall
goimportsmanually and make sureGOPATH/binis in the PATH of VS Code’s terminal.
Once this setup is complete, you have a solid Go environment: a language server with full autocomplete, auto-formatting on save, a working debugger with breakpoints, and a ready-to-run test suite. From here you can start building REST APIs, CLI tools, or microservices — without ever worrying about the environment again.

