goreleaser/goreleaser · error

ko: missing repositories: please set either the repository f

Error message

ko: missing repositories: please set either the repository field or a $KO_DOCKER_REPO environment variable

What it means

The ko pipe needs to know which container registry/repository to push images to. ko determines this from the ko.repository config field or the $KO_DOCKER_REPO environment variable; when neither is set, no repositories can be resolved and Default/buildBuildOptions (and Run) fail with errNoRepositories.

Source

Thrown at internal/pipe/ko/ko.go:58

	"github.com/goreleaser/goreleaser/v2/pkg/context"
	"golang.org/x/tools/go/packages"
)

const chainguardStatic = "cgr.dev/chainguard/static"

var (
	baseImages     sync.Map
	amazonKeychain authn.Keychain = authn.NewKeychainFromHelper(ecr.NewECRHelper(ecr.WithLogger(io.Discard)))
	azureKeychain  authn.Keychain = authn.NewKeychainFromHelper(credhelper.NewACRCredentialsHelper())
	keychain                      = authn.NewMultiKeychain(
		amazonKeychain,
		authn.DefaultKeychain,
		google.Keychain,
		github.Keychain,
		azureKeychain,
	)

	errNoRepositories    = errors.New("ko: missing repositories: please set either the repository field or a $KO_DOCKER_REPO environment variable")
	errInvalidMainPath   = errors.New("ko: invalid Main path: ko.main (or build.main if ko.main is not set) should be a relative path")
	errInvalidMainGoPath = errors.New("ko: invalid Main path: your path should point to a directory instead of a .go file")
)

// Pipe that build OCI compliant images with ko.
type Pipe struct{}

func (Pipe) String() string { return "ko" }
func (Pipe) Skip(ctx *context.Context) bool {
	return skips.Any(ctx, skips.Ko) || len(ctx.Config.Kos) == 0
}

// Default sets the Pipes defaults.
func (Pipe) Default(ctx *context.Context) error {
	ids := ids.New("kos")
	for i := range ctx.Config.Kos {
		ko := &ctx.Config.Kos[i]
		if ko.ID == "" {

View on GitHub (pinned to f5edd73956)

Solutions

  1. Set repository in the ko section of .goreleaser.yaml (e.g. repository: ghcr.io/user/app)
  2. Or export KO_DOCKER_REPO=registry/repo in the build environment
  3. Re-run goreleaser after setting either value

Example fix

# before (goreleaser.yaml)
ko:
  build: build
# after
ko:
  build: build
  repository: ghcr.io/myorg/myapp
Defensive patterns

Strategy: validation

Validate before calling

if ko.Repository == "" && os.Getenv("KO_DOCKER_REPO") == "" {
    return errors.New("ko: set ko.repository or KO_DOCKER_REPO before releasing")
}

Try / catch

if err := koPipe.Default(ctx); err != nil {
    if errors.Is(err, ko.ErrNoRepositories) {
        return fmt.Errorf("configure ko.repository in .goreleaser.yaml or export KO_DOCKER_REPO: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: ko section present in .goreleaser.yaml (or ko used in tests) with no repository field and no KO_DOCKER_REPO env var set; also at internal/pipe/ko/ko.go:442 when opts.imageRepos ends up empty after option building.

Common situations: CI environments where KO_DOCKER_REPO is not exported; adding a ko section but only setting base_image_importpath; forgetting the repository key when migrating from another image pipe.

Related errors


AI-assisted analysis of goreleaser/goreleaser@f5edd73956 (2026-09-05). Data as JSON: /api/errors/36a4a6c82f20a154. Report an issue: GitHub.