The scenario
You cloned a repository from GitHub, opened the terminal, and typed go run main.go. The shell responded with command not found: go. You remember installing a language runtime on your old machine, but Fedora does not ship with Go preloaded. You need the compiler, the standard library, and a working directory structure before you can compile a single line of code. You also need to understand where Go expects to find your dependencies and where it places the tools you install later.
How Go actually installs on Fedora
Go is a compiled language that bundles its own toolchain. The compiler, linker, and standard library live together in a single directory tree called GOROOT. When you run go build, the toolchain reads your source files, resolves dependencies, and outputs a static binary. Fedora packages this toolchain in the golang package, but the upstream Go team releases new versions every few months. Fedora’s package manager prioritizes stability and integration with the system, which means the version in the repositories might lag behind the absolute latest upstream release. You have two paths forward. You can let Fedora manage the installation and updates, or you can download the official tarball and manage the version yourself. Both approaches work. The difference lies in who controls the update cycle and where the binaries live on your filesystem.
Think of GOROOT as the engine room. It contains the compiler and the standard library. You never modify it. GOPATH is your workshop. It stores downloaded modules, cached builds, and binaries you install with go install. Modern Go defaults GOPATH to ~/go, but explicit configuration removes ambiguity when multiple projects share the same machine.
Install Go via dnf
Here is how to install Go through Fedora’s package manager. This method integrates with your system’s dependency resolver and updates alongside the rest of your packages.
sudo dnf install golang golang-docs
# golang provides the compiler, linker, and standard library. golang-docs pulls in the offline documentation for your browser.
go version
# Verify the toolchain installed correctly and prints the release number.
Fedora’s package sets GOROOT automatically. You do not need to configure environment variables for the compiler to find its own files. Your personal projects will live in ~/go by default. This directory acts as your GOPATH, which is where Go stores downloaded modules and compiled binaries. The golang package also installs the go command into /usr/bin, so it is available in every terminal session without extra configuration.
Run dnf upgrade --refresh when you want to pull the latest Fedora-packaged Go release. The package manager handles the replacement cleanly. dnf system-upgrade is for crossing major Fedora releases. They are different commands. Don't conflate them. Reboot before you debug. Half the time the symptom is gone.
Install Go from the official tarball
Here is how to install the exact upstream version when Fedora’s repository is too old for your project. This method gives you precise control over the Go version but requires manual updates.
GO_VERSION=1.22.4
curl -Lo /tmp/go${GO_VERSION}.linux-amd64.tar.gz https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz
# Download the official tarball to a temporary location. Replace the version number if a newer release exists.
sudo rm -rf /usr/local/go
# Remove any previous tarball installation to avoid version conflicts.
sudo tar -C /usr/local -xzf /tmp/go${GO_VERSION}.linux-amd64.tar.gz
# Extract the archive directly into /usr/local. The tarball already contains the 'go' directory structure.
The tarball places the toolchain in /usr/local/go. This directory is not in your default PATH. You need to tell your shell where to find the go binary. Edit your shell configuration file and append the export lines. Use ~/.bashrc for Bash or ~/.zshrc for Zsh.
export PATH=$PATH:/usr/local/go/bin
# Add the Go binary directory to the front of your search path.
export GOPATH=$HOME/go
# Explicitly set your workspace directory. Modern Go defaults to this anyway, but stating it removes ambiguity.
export PATH=$PATH:$GOPATH/bin
# Add your local bin directory so installed tools run without typing the full path.
Reload your shell configuration to apply the changes immediately.
source ~/.bashrc
# Apply the new environment variables to the current terminal session.
go version
# Confirm the tarball version is active and matches the release you downloaded.
Config files in /etc/ are user-modified. Files in /usr/lib/ ship with the package. Edit /etc/. Never edit /usr/lib/. The same principle applies to Go. Keep your workspace in ~/go and leave /usr/local/go untouched. Manual file edits drift, snapshots stay.
Set up your workspace and run a project
Go modules replaced the old GOPATH dependency system years ago. Modules track your project’s dependencies in a go.mod file and download them into a local cache. You do not need to manage vendor directories anymore. The module proxy fetches dependencies from proxy.golang.org by default, which caches releases and provides deterministic builds.
Create a new directory for your project and initialize the module.
mkdir ~/projects/hello && cd ~/projects/hello
go mod init example.com/hello
# Create the go.mod file. The module path can be any string, but using a domain you control prevents import collisions.
Write a minimal program in main.go.
package main
import "fmt"
func main() {
fmt.Println("Hello, Fedora!")
}
Run the program directly from the source directory.
go run .
# Compile and execute the current directory. The dot tells Go to look for main.go in the current folder.
Build a standalone binary when you need to distribute the application or run it without the Go toolchain installed.
go build -o hello .
# Compile the source into a static executable named 'hello'.
./hello
# Run the compiled binary. It contains the standard library and all dependencies.
Verify it worked. The terminal should print Hello, Fedora! without errors. If you see a module error, you are likely running the command outside the project directory or forgot to initialize the module. Run go mod tidy after adding new imports to clean up unused dependencies.
Add tooling and editor support
The Go toolchain includes the compiler and standard library. It does not include language servers, linters, or formatters. You install these tools as separate binaries using go install. The binaries land in $GOPATH/bin, which is why the PATH export from the tarball section matters.
Install the official language server and a popular linter.
go install golang.org/x/tools/gopls@latest
# Download and compile gopls. This provides autocomplete, go-to-definition, and refactoring in your editor.
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
# Install the linter aggregator. It runs multiple static analysis tools in a single pass.
gofmt -w .
# Apply Go's standard formatting rules to every file in the current directory.
Most developers use VS Code or GoLand on Fedora. VS Code runs well as a Flatpak, which isolates it from system libraries and matches the desktop sandboxing model.
flatpak install flathub com.visualstudio.code
# Install VS Code from Flathub. Flatpak handles runtime dependencies automatically.
Open VS Code, install the official Go extension, and run Go: Install/Update Tools from the command palette. The extension will download gopls, dlv (the debugger), and gopkgs into your $GOPATH/bin directory. If the extension complains about missing tools, check your PATH variable. The Flatpak sandbox sometimes restricts access to $GOPATH/bin. You can work around this by setting go.goroot and go.gopath in VS Code settings, or by running the editor from the terminal with flatpak run com.visualstudio.code. Trust the package manager. Manual file edits drift, snapshots stay.
Common pitfalls and error messages
You will encounter a few predictable errors when setting up Go on Fedora. Knowing the exact wording saves you from guessing.
The go run command will refuse to proceed and print the following:
go: cannot find main module; see 'go help modules'
This happens when you run the command in a directory that lacks a go.mod file. Initialize the module first.
If you see command not found: gopls after running go install, your $GOPATH/bin directory is not in your PATH. Check your shell configuration file and reload it with source.
The go build command might fail with undefined: main if your file is not in the package main namespace or if the main function signature is incorrect. Go requires exactly one package main with a func main() entry point for executable binaries.
SELinux denials show up in journalctl -t setroubleshoot with a one-line summary. Read those before disabling SELinux. Go binaries run with standard user permissions, so SELinux rarely blocks development work. If a custom daemon fails to start, check the audit log before assuming a compiler bug. Run journalctl -xe first. Read the actual error before guessing.
Which installation method fits your workflow
Use the dnf install golang method when you want automatic updates, system integration, and minimal configuration. Use the official tarball when you need a specific upstream version that Fedora has not packaged yet. Use the tarball when you are managing multiple Go versions for different projects. Stay on the dnf package if you only deviate from the defaults occasionally.