Fix: Go undefined: variable (or function)
Quick Answer
How to fix Go undefined error caused by undeclared variables, wrong package scope, unexported names, missing imports, build tags, and file organization issues.
The Error
You compile a Go program and get:
./main.go:10:5: undefined: myVariableOr variations:
./main.go:15:2: undefined: MyFunction./handler.go:8:12: undefined: Config./main.go:5:2: undefined: fmtThe Go compiler cannot find the variable, function, type, or package you referenced. It either does not exist in the current scope, is in a different package, or is not exported.
Why This Happens
Go resolves names at compile time with strict rules:
- Variables must be declared before use.
- Functions and types must be defined in the same package or imported.
- Names starting with lowercase are unexported (private to the package).
- Names starting with uppercase are exported (accessible from other packages).
- Each file must import the packages it uses.
Common causes:
- Variable not declared. You used a name that was never declared with
var,:=, or as a function parameter. - Wrong package scope. The name is defined in a different package but not imported or exported.
- Unexported name. You are trying to use a lowercase name from another package.
- Missing import. The package is not imported in the current file.
- File not included in build. Build tags or wrong file naming excludes the file.
- Typo. The name is misspelled.
Fix 1: Declare the Variable
The simplest case. You used a variable that was never declared:
Broken:
func main() {
fmt.Println(message) // undefined: message
}Fixed:
func main() {
message := "Hello, World!"
fmt.Println(message)
}Or declare at package level:
var message = "Hello, World!"
func main() {
fmt.Println(message)
}Go does not have implicit variable creation. Every variable must be explicitly declared with var, :=, or as a function parameter.
Fix 2: Import the Package
If fmt, os, http, or any standard library name is undefined, the package is not imported:
Broken:
func main() {
fmt.Println("Hello") // undefined: fmt
}Fixed:
import "fmt"
func main() {
fmt.Println("Hello")
}Multiple imports:
import (
"fmt"
"net/http"
"os"
)Most Go editors (VS Code with gopls, GoLand) auto-add imports when you save. If auto-import is not working, check your editor’s Go extension settings.
Pro Tip: Use
goimportsto automatically add and remove imports:go install golang.org/x/tools/cmd/goimports@latest goimports -w .Configure your editor to run
goimportson save. This eliminates all manual import management.
Fix 3: Export Names with Uppercase
In Go, lowercase names are private to the package. To use a name from another package, it must start with an uppercase letter:
Broken — unexported name:
// config/config.go
package config
var databaseURL = "postgres://localhost/mydb" // lowercase — unexported// main.go
package main
import "myapp/config"
func main() {
fmt.Println(config.databaseURL) // undefined: config.databaseURL
}Fixed — export with uppercase:
// config/config.go
package config
var DatabaseURL = "postgres://localhost/mydb" // Uppercase — exported// main.go
fmt.Println(config.DatabaseURL) // WorksThis applies to variables, functions, types, constants, and struct fields. If a struct field is lowercase, other packages cannot access it directly.
For similar Go issues with unused variables, see Fix: Go declared and not used.
Fix 4: Fix File Organization in the Same Package
All .go files in the same directory must have the same package name. Functions and types defined in one file are visible in other files of the same package:
myapp/
main.go ← package main
handlers.go ← package main (same package!)
utils.go ← package main (same package!)Broken — wrong package name:
// handlers.go
package handlers // Wrong! Must be 'main' if in the same directory as main.go
func HandleRequest() {}Fixed:
// handlers.go
package main
func HandleRequest() {}Run all files together:
go run main.go handlers.go utils.go
# Or better:
go run .If you run only go run main.go, Go does not compile handlers.go, and names defined there are undefined.
Common Mistake: Running
go run main.goinstead ofgo run .when your package has multiple files.go run main.goonly compiles that single file.go run .compiles all.gofiles in the current directory with the same package name.
Fix 5: Fix Test File Issues
Names from _test.go files are not available in non-test files:
// helpers_test.go
package main
func testHelper() string {
return "test"
}// main.go
package main
func main() {
testHelper() // undefined: testHelper (only exists in test files)
}Test files (_test.go) are compiled only during go test. Move shared helpers to a regular .go file if they are needed outside tests.
External test packages: Files with package main_test are in a different package and can only access exported names:
// math_test.go
package math_test // External test package
import "myapp/math"
func TestAdd(t *testing.T) {
result := math.Add(2, 3) // Must use exported name
}Fix 6: Fix Build Tags
Build tags can exclude files from compilation. A file with a build tag is only compiled when the tag matches:
//go:build linux
package main
func platformSpecific() {}This file is only compiled on Linux. On macOS or Windows, platformSpecific is undefined.
Check your build tags:
go build -tags "linux" .Common build tags:
//go:build linux— only on Linux//go:build !windows— everything except Windows//go:build integration— only when-tags integrationis specified
If you need a function on all platforms, move it to a file without build tags or create platform-specific implementations:
utils_linux.go ← //go:build linux
utils_darwin.go ← //go:build darwin
utils_windows.go ← //go:build windowsFix 7: Fix Go Module Issues
If the undefined name is from an external package, the module might not be installed:
go mod tidyThis downloads missing dependencies and removes unused ones.
If the module is not found:
go get github.com/example/package@latestFor Go module resolution errors, see Fix: Go module not found. For “no required module provides package” errors, see Fix: Go no required module provides package.
Fix 8: Fix init() and Package Initialization
init() functions run automatically and cannot be called explicitly:
func init() {
// Runs automatically when package is loaded
}
func main() {
init() // Cannot call init explicitly — but this is a different error
}If you need initialization logic that can be called manually, use a regular function name like Initialize().
Package-level variables are initialized before init():
var config = loadConfig() // Runs first
func init() {
// config is available here
}
func main() {
// Both config and init() have already run
}Still Not Working?
If the error persists:
Check for generated code. Some Go projects use code generation (go generate, protobuf, sqlc, ent). Run the generator before building:
go generate ./...
go build .Check for CGO dependencies. If the code uses import "C" (cgo), you need a C compiler installed. Without it, the cgo file is skipped and names defined there are undefined:
# Install gcc
sudo apt install gcc
# Or disable CGO if not needed
CGO_ENABLED=0 go build .Check the Go version. Some features (generics, any type, min/max builtins) require a minimum Go version. Check your go.mod:
module myapp
go 1.22Update if needed:
go install golang.org/dl/go1.22.0@latestCheck for interface embedding issues. If a type is supposed to implement an interface but methods are missing, the compiler might report “undefined” on the method call rather than a clear “does not implement” error.
Use your IDE. VS Code with gopls highlights undefined names immediately and offers “Quick Fix” suggestions. Install the Go extension and ensure gopls is running:
go install golang.org/x/tools/gopls@latestSolo developer based in Japan. Every solution is cross-referenced with official documentation and tested before publishing.
Was this article helpful?
Related Articles
Fix: Go cannot find package / no required module provides package
How to fix 'cannot find package' and 'no required module provides package' errors in Go by syncing dependencies, fixing import paths, configuring private repos, and resolving workspace issues.
Fix: Go fatal error: all goroutines are asleep - deadlock!
How to fix Go fatal error all goroutines are asleep deadlock caused by unbuffered channels, missing goroutines, WaitGroup misuse, and channel direction errors.
Fix: Go panic: runtime error: index out of range
How to fix Go panic runtime error index out of range caused by empty slices, off-by-one errors, nil slices, concurrent access, and missing bounds checks.
Fix: Go cannot use X (type Y) as type Z in argument
How to fix Go 'cannot use as type' error caused by type mismatches, interface satisfaction, pointer vs value receivers, type conversions, and generic constraints.