undefined: <functionname>
The fastest fix: check your import block — the package that provides the function is almost certainly missing. Add import "packagepath" and the error disappears in most cases.
Before (broken):
package main
func main() {
fmt.Println("hello") // undefined: fmt
}
After (fixed):
package main
import "fmt"
func main() {
fmt.Println("hello")
}
If the import is already present, read on — there are four other causes.
Why This Happens
Go resolves every identifier at compile time. When you write fmt.Println, the compiler looks for a package named fmt in your import block, then verifies that Println is exported from that package. If either check fails, you get undefined. There is no runtime lookup, no dynamic dispatch at the point of name resolution — every name must be provably resolvable before a single line executes.
Cause 1: Missing Import
The most common cause by far. You are using a package — from the standard library or a third-party module — without importing it.
Broken:
package main
func main() {
// Using os, strings, and strconv without importing them
args := os.Args[1:]
upper := strings.ToUpper(args[0])
n, _ := strconv.Atoi(args[1])
fmt.Println(upper, n)
}
Fixed:
package main
import (
"fmt"
"os"
"strconv"
"strings"
)
func main() {
args := os.Args[1:]
upper := strings.ToUpper(args[0])
n, _ := strconv.Atoi(args[1])
fmt.Println(upper, n)
}
Pro tip: Install goimports (go install golang.org/x/tools/cmd/goimports@latest) and configure your editor to run it on save. It automatically adds missing imports and removes unused ones, making this entire class of error impossible in practice.
Cause 2: Typo in the Function Name
Go is case-sensitive. Println, println, and PrintLn are three different identifiers. Exported functions (usable outside their package) start with an uppercase letter; unexported ones start with lowercase.
Broken:
package main
import "fmt"
func main() {
fmt.println("hello") // lowercase p — undefined: fmt.println
fmt.Printl("world") // missing n — undefined: fmt.Printl
}
Fixed:
package main
import "fmt"
func main() {
fmt.Println("hello")
fmt.Println("world")
}
Common typos to watch for:
- Unmarshal vs Unmarshall (one l)
- Sprintf vs SPrintf or sprintf
- WriteString vs Writestring
- ParseInt vs Parseint
Your IDE's autocompletion is the best defence here. If the function does not appear in the autocomplete list after the dot, it does not exist under that name.
Cause 3: Wrong Package Name in the Call
When you import a package, you reference its exported symbols via the package's last path segment (or the name the package declares with package pkgname). Using the wrong prefix causes an undefined error even when the import is correct.
Broken:
package main
import "encoding/json"
type User struct {
Name string `json:"name"`
}
func main() {
u := User{Name: "Alice"}
data, _ := encoding.Marshal(u) // wrong: "encoding" is not the package name
fmt.Println(string(data))
}
Fixed:
package main
import (
"encoding/json"
"fmt"
)
type User struct {
Name string `json:"name"`
}
func main() {
u := User{Name: "Alice"}
data, _ := json.Marshal(u) // correct: use "json", the package's declared name
fmt.Println(string(data))
}
When a package's declared name differs from its import path (common in third-party packages), use an alias:
import (
myhttp "net/http" // alias if you want to rename
)
Cause 4: Unexported Function from Another Package
In Go, only identifiers that start with an uppercase letter are exported (visible outside the package). If you define func helper() in a package and try to call it from another package, you get undefined.
Package mathutils (in ./mathutils/mathutils.go):
package mathutils
// exported — uppercase H
func HalfOf(n float64) float64 {
return n / 2
}
// unexported — lowercase d
func doubleOf(n float64) float64 {
return n * 2
}
main.go (broken):
package main
import (
"fmt"
"mymodule/mathutils"
)
func main() {
fmt.Println(mathutils.HalfOf(10)) // works: exported
fmt.Println(mathutils.doubleOf(10)) // undefined: mathutils.doubleOf
}
Fixed — option A: export the function:
// mathutils/mathutils.go
func DoubleOf(n float64) float64 { // uppercase D
return n * 2
}
Fixed — option B: use the function only within its package:
// mathutils/mathutils.go
func ProcessNumber(n float64) float64 {
return doubleOf(n) // calling unexported func from within same package — fine
}
The rule is simple: if the first letter is uppercase, it is public; if lowercase, it is package-private.
Cause 5: Wrong Module Path or Missing go get
When using third-party packages, the module must be listed in go.mod and downloaded to the module cache. If you add an import without running go get, the package does not exist locally.
Broken — go.mod does not list the dependency:
package main
import (
"fmt"
"github.com/pkg/errors" // not in go.mod yet
)
func main() {
err := errors.New("something went wrong")
fmt.Println(err)
}
Running go build produces:
cannot find module providing package github.com/pkg/errors
Sometimes expressed as undefined: errors if the module partially resolves.
Fixed:
# Add the dependency and update go.mod + go.sum
go get github.com/pkg/errors
# Or, if you have already edited the import, just tidy:
go mod tidy
After go get or go mod tidy, go.mod will contain the dependency and the build succeeds.
Also check: If you cloned a repository and dependencies are missing, run go mod download or go mod tidy to restore them.
Cause 6: Calling a Function Defined in a Different Build Tag Context
Go's build tag system can exclude files from compilation. If the function you are calling is defined in a file that is excluded by build tags (e.g., //go:build linux and you are on Windows), the function simply does not exist in the current build.
Broken — platform_linux.go:
//go:build linux
package main
func getPlatformInfo() string {
return "running on Linux"
}
main.go on Windows:
package main
import "fmt"
func main() {
fmt.Println(getPlatformInfo()) // undefined on Windows
}
Fixed — provide a stub for other platforms in platform_other.go:
//go:build !linux
package main
func getPlatformInfo() string {
return "running on non-Linux platform"
}
Quick Diagnosis Checklist
| Check | Command / Action |
|---|---|
| Is the package imported? | Look at the import (...) block |
| Is the function name spelled correctly? | Use IDE autocompletion |
| Is the function exported (uppercase)? | Check the function definition in its package |
Is the module in go.mod? |
cat go.mod or go list -m all |
| Is the dependency downloaded? | go mod download |
| Are build tags excluding the file? | go list -f '{{.IgnoredGoFiles}}' ./... |
Related Guides
- Most Common Golang Errors and How to Fix Them
- Fix 'imported and not used' Error in Go
- go mod tidy Explained
- Fix Golang compile version mismatch errors
FAQ
Why does Go not have auto-import like some other languages?
Go does have it — via the goimports tool and editor integrations. The language itself requires explicit imports in source files for reproducibility and clarity, but your editor can manage them automatically. Run go install golang.org/x/tools/cmd/goimports@latest and configure your editor to format with goimports on save.
Can I import a package and give it a different name?
Yes. Use an import alias: import myjson "encoding/json". After that, use myjson.Marshal(...) instead of json.Marshal(...). A common alias is _ for side-effect-only imports (like database drivers) and . to import all exported names into the current namespace (generally discouraged).
I fixed the import but the error persists — what now?
Try these steps in order: (1) run go mod tidy to sync dependencies, (2) run go clean -cache to clear stale build artifacts, (3) verify the package name matches what you are calling (e.g., import "encoding/json" is called with json., not encoding.), (4) check if the function is unexported (starts with lowercase).