grpc-ecosystem/grpc-gateway · error

package name %s is already taken. Use another alias

Error message

package name %s is already taken. Use another alias

What it means

ReserveGoPackageAlias registers a Go package alias used when generating imports. If the alias is already reserved for a DIFFERENT package path, the registry rejects it to avoid two distinct proto packages mapping to the same Go import name. Reserving the same alias for the same package path is idempotent and returns nil.

Source

Thrown at internal/descriptor/registry.go:490

func (r *Registry) SetRecursiveDepth(count int) {
	r.recursiveDepth = count
}

// GetRecursiveDepth returns the max recursion count
func (r *Registry) GetRecursiveDepth() int {
	return r.recursiveDepth
}

// ReserveGoPackageAlias reserves the unique alias of go package.
// If succeeded, the alias will be never used for other packages in generated go files.
// If failed, the alias is already taken by another package, so you need to use another
// alias for the package in your go files.
func (r *Registry) ReserveGoPackageAlias(alias, pkgpath string) error {
	if taken, ok := r.pkgAliases[alias]; ok {
		if taken == pkgpath {
			return nil
		}
		return fmt.Errorf("package name %s is already taken. Use another alias", alias)
	}
	r.pkgAliases[alias] = pkgpath
	return nil
}

// GetAllFQMNs returns a list of all FQMNs
func (r *Registry) GetAllFQMNs() []string {
	keys := make([]string, 0, len(r.msgs))
	for k := range r.msgs {
		keys = append(keys, k)
	}
	return keys
}

// GetAllFQENs returns a list of all FQENs
func (r *Registry) GetAllFQENs() []string {
	keys := make([]string, 0, len(r.enums))
	for k := range r.enums {

View on GitHub (pinned to a58a4436a3)

Solutions

  1. Change the go_package option in one of the conflicting .proto files so each package path yields a unique alias
  2. Import the conflicting proto with an explicit import_alias in the proto that references it
  3. If generating with protoc-gen-openapiv2, adjust M flags to remap go_package paths uniquely
  4. If the alias is intentionally the same package, ensure the pkgpath argument matches exactly (identical alias+path is allowed)

Example fix

// before
option go_package = "example.com/api/v1;v1";   // in a.proto
option go_package = "example.com/other/v1;v1";  // in b.proto -> alias 'v1' collision
// after
option go_package = "example.com/api/v1;apiv1";
option go_package = "example.com/other/v1;otherv1";
Defensive patterns

Strategy: validation

Validate before calling

if existing, ok := registryAliases[alias]; ok && existing != pkgpath {
    return fmt.Errorf("alias %q already reserved for %q", alias, pkgpath)
}
_ = registry.ReserveGoPackageAlias(alias, pkgpath)

Prevention

When it happens

Trigger: Calling Registry.ReserveGoPackageAlias(alias, pkgpath) when r.pkgAliases[alias] exists and maps to a different pkgpath. Happens during loadFile/New when two proto files declare go_package paths that collapse to the same alias.

Common situations: Two .proto files in different directories share the same go_package basename (e.g. both use 'v1' as the final package element); vendored third-party protos whose go_package collides with local protos; monorepo merges introducing a second API version with an identical alias.

Related errors


AI-assisted analysis of grpc-ecosystem/grpc-gateway@a58a4436a3 (2026-09-02). Data as JSON: /api/errors/ef6df7251c8dcce8. Report an issue: GitHub.