}

Fix Golang 'undefined: function' Error — All Causes (2026)

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


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).