}

Fix 'undefined: functionName' Error in Go (2026)

./main.go:X:Y: undefined: functionName

The undefined: functionName error means the Go compiler cannot find the name you are using in the current scope. The one-line fix is to check spelling, ensure the package is imported, and verify the function is exported if it lives in another package.

The Full Error

./main.go:8:14: undefined: greet

Or across packages:

./main.go:12:5: undefined: utils.helper

The compiler tells you the file, line, and column where the unknown name appears. The name itself is everything after undefined:.


Cause 1: Simple Typo

The most frequent cause. Go is case-sensitive: Println and println are different names.

Broken code:

package main

import "fmt"

func main() {
    fmt.Printl("hello")  // typo: Printl instead of Println
}

Error:

./main.go:6:5: undefined: fmt.Printl

Fixed code:

package main

import "fmt"

func main() {
    fmt.Println("hello")  // correct spelling
}

How to find typos fast: Run go build ./... — the error line and column point you directly to the bad character. In VS Code with the Go extension, a red squiggle appears under the misspelled name before you even save.


Cause 2: Function Defined in a Different File — Same Package

If your function lives in another file in the same directory, it is automatically visible as long as both files declare package main (or the same package name). No import is needed.

Broken scenario: Two files, but one accidentally has a different package name.

helpers.go (broken):

package helpers   // wrong — should be package main

func greet(name string) string {
    return "Hello, " + name
}

main.go:

package main

import "fmt"

func main() {
    fmt.Println(greet("world"))  // undefined: greet
}

Fixed helpers.go:

package main   // same package as main.go

func greet(name string) string {
    return "Hello, " + name
}

Run with go run . (the dot) to include all .go files in the directory, not go run main.go which compiles only a single file.


Cause 3: Function Not Exported (Lowercase Name)

In Go, a name is exported (visible outside its package) only if it starts with an uppercase letter. A lowercase function name is private to its package.

utils/math.go (broken):

package utils

// lowercase — not exported, invisible outside this package
func add(a, b int) int {
    return a + b
}

main.go:

package main

import (
    "fmt"
    "mymodule/utils"
)

func main() {
    fmt.Println(utils.add(1, 2))  // undefined: utils.add
}

Error:

./main.go:9:18: undefined: utils.add

Note: the error says undefined, not "unexported". Go intentionally makes private names completely invisible — they do not exist from outside the package.

Fixed utils/math.go:

package utils

// Uppercase A — exported, visible to importing packages
func Add(a, b int) int {
    return a + b
}

Fixed main.go:

package main

import (
    "fmt"
    "mymodule/utils"
)

func main() {
    fmt.Println(utils.Add(1, 2))  // works: 3
}

Cause 4: Missing Import

If you use a package function without importing the package, you get undefined.

Broken code:

package main

func main() {
    Println("hello")  // undefined: Println — forgot import "fmt"
}

Or with the package name prefix but no import:

package main

func main() {
    fmt.Println("hello")  // undefined: fmt — import is missing
}

Fixed code:

package main

import "fmt"

func main() {
    fmt.Println("hello")
}

Pro tip: Use goimports instead of gofmt. It automatically adds missing imports and removes unused ones every time you save. Install it once:

go install golang.org/x/tools/cmd/goimports@latest

Configure VS Code to use it:

{
    "editor.formatOnSave": true,
    "[go]": {
        "editor.defaultFormatter": "golang.go"
    },
    "go.formatTool": "goimports"
}

Cause 5: Wrong Package Path or Alias

If you import a package under a different path than how you call it, the compiler sees an undefined name.

Broken code:

package main

import (
    "fmt"
    myrandom "math/rand"   // aliased as myrandom
)

func main() {
    fmt.Println(rand.Intn(100))  // undefined: rand — should use myrandom
}

Fixed code:

package main

import (
    "fmt"
    myrandom "math/rand"
)

func main() {
    fmt.Println(myrandom.Intn(100))  // correct: use the alias
}

Or remove the alias:

import (
    "fmt"
    "math/rand"
)

func main() {
    fmt.Println(rand.Intn(100))  // works
}

Cause 6: Circular Imports

Go forbids circular imports: package A cannot import package B if B already imports A. When a circular import exists, you typically see a cascade of undefined errors or an explicit:

import cycle not allowed

Broken structure:

myapp/
├── a/a.go    (imports "myapp/b")
└── b/b.go    (imports "myapp/a")   ← circular!

Fix strategies:

  1. Extract shared code to a third package that neither A nor B imports: myapp/shared
  2. Merge the two packages if they are genuinely co-dependent
  3. Use an interface in the importing package instead of importing the concrete type
myapp/
├── a/a.go      (imports "myapp/shared")
├── b/b.go      (imports "myapp/shared")
└── shared/     (imported by both, imports neither)

Cause 7: Build Tag Excluding the File

A //go:build constraint at the top of a file can exclude it from the build entirely, making its functions invisible.

//go:build linux

package main

func platformHelper() string {
    return "linux specific"
}

If you build on macOS or Windows, platformHelper is undefined because the file is excluded.

Fix: Either remove the build tag, provide a fallback file without the constraint, or build with the correct GOOS:

GOOS=linux go build ./...

Diagnosis Checklist

Question If yes → Fix
Is the name spelled correctly (including case)? Fix the typo
Does the function live in another file with the same package name? Run go run . not go run main.go
Does the function start with lowercase? Capitalize it to export, or move caller into the same package
Is the package imported? Add the import or run goimports
Is the package aliased? Use the alias, not the last segment of the import path
Is there a build tag on the file containing the function? Remove the tag or set correct GOOS/GOARCH
Does the error mention "import cycle"? Refactor to remove the circular dependency

FAQ

Q: Why does Go say undefined instead of "private" or "unexported"?

A: By design. From outside a package, private names do not exist at all — they are not visible, not accessible, and the compiler behaves as if they were never declared. This is different from languages like Java where private members are visible but access is checked.

Q: I added the import but still get undefined: pkg.FunctionName. What now?

A: Check three things: (1) the import path is the full module path, not just the package name — e.g., "github.com/user/repo/utils" not just "utils"; (2) the function name is exported (starts with uppercase); (3) you have run go mod tidy so the module is present in go.sum.

Q: Can I call a private function from a test file in the same package?

A: Yes. A test file named foo_test.go that declares package foo (not package foo_test) is part of the same package and can access all private names. This is Go's built-in white-box testing mechanism.


Related Articles