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
- Find and kill the process holding the port (lsof -i :<port> or netstat) or the stale skaffold process.
- Start with a different --port / preferredPort value so listenPort can bind successfully.
- Check you are not trying to bind a privileged port (<1024) without elevated permissions.
- 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
- Check port availability with net.Listen before starting skaffold servers.
- Kill stale skaffold processes before starting a new dev session.
- Avoid hardcoding the same port across concurrent dev sessions.
- Log the wrapped cause (%w) to distinguish EADDRINUSE from EACCES.
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
- error closing GCS writer: %w
- starting gRPC server: %w
- uploading sources to google storage: %w
- INIT_DOCKER_NETWORK_CONTAINER_DOES_NOT_EXIST
- initializing api server: %w
AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05).
Data as JSON: /api/errors/4cefb18a377eee55.
Report an issue: GitHub.