golang/go · error · PackageError

binary-only packages are no longer supported

Error message

binary-only packages are no longer supported

What it means

The //go:binary-only-package pragma was a GOPATH-era mechanism to distribute a package as a precompiled .a file without source. Support was removed; the loader now unconditionally errors when p.BinaryOnly is true. The package cannot be built, imported, or used in module mode.

Solutions

  1. Obtain the source code for the package and remove the //go:binary-only-package comment.
  2. Replace the closed-source dependency with an open-source or source-available alternative module.
  3. Publish the library through a private module proxy that serves source so the go command can build it.

Example fix

// before (stub.go):
//go:binary-only-package
package foo

// after: provide the real source, remove the pragma line
package foo
Defensive patterns

Strategy: validation

Validate before calling

// Scan for the pragma before building:
//   grep -rn "go:binary-only-package" .
// If found, remove the comment and provide source, or replace the dependency.

Prevention

When it happens

Trigger: A Go source file in the package (or its documented stub) contains the `//go:binary-only-package` comment, causing p.BinaryOnly to be set during package load.

Common situations: Legacy projects migrated from GOPATH that depended on closed-source binary-only libraries; vendored commercial libraries once shipped as .a files; old documentation or tutorials suggesting the pragma.

Related errors


AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12). Data as JSON: /api/errors/ae623cf3a61fc39e. Report an issue: GitHub.

Appendix: source

Thrown at src/cmd/go/internal/load/pkg.go:2001

		foldPath[fold] = p.ImportPath
	} else if other != p.ImportPath {
		setError(ImportErrorf(p.ImportPath, "case-insensitive import collision: %q and %q", p.ImportPath, other))
		return
	}

	if !SafeArg(p.ImportPath) {
		setError(ImportErrorf(p.ImportPath, "invalid import path %q", p.ImportPath))
		return
	}

	// Errors after this point are caused by this package, not the importing
	// package. Pushing the path here prevents us from reporting the error
	// with the position of the import declaration.
	stk.Push(ImportInfo{Pkg: path, Pos: extractFirstImport(importPos)})
	defer stk.Pop()

	if p.BinaryOnly {
		setError(errors.New("binary-only packages are no longer supported"))
	}

	pkgPath := p.ImportPath
	if p.Internal.CmdlineFiles {
		pkgPath = "command-line-arguments"
	}
	if cfg.ModulesEnabled {
		p.Module = modload.PackageModuleInfo(ld, ctx, pkgPath)
	}
	p.DefaultGODEBUG = defaultGODEBUG(ld, p, nil, nil, nil)

	if !opts.SuppressEmbedFiles {
		p.EmbedFiles, p.Internal.Embed, err = resolveEmbed(p.Dir, p.EmbedPatterns)
		if err != nil {
			p.Incomplete = true
			setError(err)
			embedErr := err.(*EmbedError)
			p.Error.setPos(p.Internal.Build.EmbedPatternPos[embedErr.Pattern])

View on GitHub (pinned to b6b368adc5)