GoogleContainerTools/skaffold · error

creating listener: %w

Error message

creating listener: %w

What it means

Skaffold's `newGRPCServer` wraps any failure from `listenPort(preferredPort)` when opening the TCP listener for the gRPC debug/user server. It means the process could not bind to a port, so the gRPC server (used for port-forward and debugging hooks) cannot start. The wrapped underlying error (e.g. from net.Listen) identifies the real cause.

Source

Thrown at pkg/skaffold/server/server.go:178

		eventV2.SaveLastLog(opts.LastLogFile)

		return errors.New(errStr)
	}
	if err != nil {
		return callback, fmt.Errorf("starting HTTP server: %w", err)
	}

	if opts.EnableRPC && opts.RPCPort.Value() == nil && opts.RPCHTTPPort.Value() == nil {
		log.Entry(context.TODO()).Warnf("started skaffold gRPC API on random port %d", grpcPort)
	}

	return callback, nil
}

func newGRPCServer(preferredPort int) (func() error, int, error) {
	l, port, err := listenPort(preferredPort)
	if err != nil {
		return func() error { return nil }, 0, fmt.Errorf("creating listener: %w", err)
	}

	log.Entry(context.TODO()).Infof("starting gRPC server on port %d", port)

	s := grpc.NewServer()
	srv = &server{
		buildIntentCallback:   func() {},
		deployIntentCallback:  func() {},
		syncIntentCallback:    func() {},
		devloopIntentCallback: func() {},
		autoBuildCallback:     func(bool) {},
		autoSyncCallback:      func(bool) {},
		autoDeployCallback:    func(bool) {},
		autoDevloopCallback:   func(bool) {},
	}
	v2.Srv = &v2.Server{
		BuildIntentCallback:   func() {},
		DeployIntentCallback:  func() {},

View on GitHub (pinned to a1189de023)

Solutions

  1. Find and kill the process holding the port (lsof -i :<port> or netstat) or the stale skaffold process.
  2. Start with a different --port / preferredPort value so listenPort can bind successfully.
  3. Check you are not trying to bind a privileged port (<1024) without elevated permissions.
  4. Inspect the wrapped error (%w) to confirm whether it is EADDRINUSE, EACCES, or a DNS/interface issue and fix accordingly.

Example fix

// before
skaffold dev --port 50051 // port already in use
// after
skaffold dev --port 50061 // pick a free port
Defensive patterns

Strategy: fallback

Validate before calling

package main

import (
  "net"
  "fmt"
)

func portFree(port int) error {
  l, err := net.Listen("tcp", fmt.Sprintf("127.0.0.1:%d", port))
  if err != nil { return err }
  return l.Close()
}
// call portFree(preferredPort) before invoking Initialize; pick another port on error

Type guard

func isAddrInUse(err error) bool {
  return errors.Is(err, syscall.EADDRINUSE)
}

Try / catch

port, cleanup, err := skaffoldServer.Initialize(...)
if err != nil {
  if strings.Contains(err.Error(), "creating listener") {
    log.Printf("port unavailable: %v; retrying with a different port", err)
    // retry with preferredPort+1 or 0 (random port)
  } else {
    return err
  }
}

Prevention

When it happens

Trigger: Calling `Initialize` with a preferredPort that is already in use, restricted (ports <1024 without privileges), or on an interface that is unavailable, causing `listenPort` to fail for the preferred port and all fallback attempts.

Common situations: Running multiple skaffold dev sessions concurrently so the default port (e.g. 50051) is taken; a zombie skaffold process still holding the port; container/sandbox environments blocking port binding; port in the ephemeral range being auto-allocated elsewhere.

Related errors


AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05). Data as JSON: /api/errors/4cefb18a377eee55. Report an issue: GitHub.