{"record":{"id":"aad9f6276d071143","repo":"GoogleContainerTools/skaffold","slug":"starting-grpc-server-w","errorCode":null,"errorMessage":"starting gRPC server: %w","messagePattern":"starting gRPC server: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/skaffold/server/server.go","lineNumber":124,"sourceCode":"}\n\n// Initialize creates the gRPC and HTTP servers for serving the state and event log.\n// It returns a shutdown callback for tearing down the grpc server,\n// which the runner is responsible for calling.\nfunc Initialize(opts config.SkaffoldOptions) (func() error, error) {\n\temptyCallback := func() error { return nil }\n\tif !opts.EnableRPC && opts.RPCPort.Value() == nil && opts.RPCHTTPPort.Value() == nil {\n\t\tlog.Entry(context.TODO()).Debug(\"skaffold API not starting as it's not requested\")\n\t\treturn emptyCallback, nil\n\t}\n\n\tpreferredGRPCPort := 0 // bind to an available port atomically\n\tif opts.RPCPort.Value() != nil {\n\t\tpreferredGRPCPort = *opts.RPCPort.Value()\n\t}\n\tgrpcCallback, grpcPort, err := newGRPCServer(preferredGRPCPort)\n\tif err != nil {\n\t\treturn grpcCallback, fmt.Errorf(\"starting gRPC server: %w\", err)\n\t}\n\n\thttpCallback := emptyCallback\n\tif opts.RPCHTTPPort.Value() != nil {\n\t\thttpCallback, err = newHTTPServer(*opts.RPCHTTPPort.Value(), grpcPort)\n\t}\n\tcallback := func() error {\n\t\t// Optionally pause execution until endpoint hit\n\t\tif opts.WaitForConnection {\n\t\t\teventV2.WaitForConnection()\n\t\t}\n\n\t\thttpErr := httpCallback()\n\t\tgrpcErr := grpcCallback()\n\t\terrStr := \"\"\n\t\tif grpcErr != nil {\n\t\t\terrStr += fmt.Sprintf(\"grpc callback error: %s\\n\", grpcErr.Error())\n\t\t}","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/GoogleContainerTools/skaffold/blob/a1189de023efc32d4b8e11f395acc678aa555011/pkg/skaffold/server/server.go#L106-L142","documentation":"server.Initialize wraps any failure from newGRPCServer — usually 'creating listener: ...' from failing to bind the preferred port — as 'starting gRPC server: %w'. Skaffold starts this gRPC API server when RPC is enabled (--rpc, --rpc-port, or --rpc-http-port) so IDEs/clients can query state and events.","triggerScenarios":"Calling Initialize(opts) with opts.EnableRPC or a non-nil RPCPort, and listenPort fails: the preferred port (--rpc-port N) is already in use by another process, the port is privileged (<1024 without permissions), or the network interface is unavailable.","commonSituations":"A stale Skaffold process still holds the configured --rpc-port; another dev tool (e.g. a debugger or another skaffold dev) is bound to the same port; running in a restricted container without the CAP_NET_BIND_SERVICE capability for low ports.","solutions":["Free the port: find and stop the process holding it (lsof -i :PORT or ss -ltnp), or remove a stale skaffold process.","Run without --rpc-port so skaffold binds a random free port (it logs the chosen port).","Choose a different, unprivileged port via --rpc-port (>=1024).","If a low port is required, grant the binary the capability or run with sufficient privileges."],"exampleFix":"// before\nskaffold dev --rpc-port 50051 // port already in use\n\n// after\nskaffold dev            # random port\n# or\nskaffold dev --rpc-port 50052","handlingStrategy":"retry","validationCode":"// check the port is free before starting\nif opts.RPCPort.Value() != nil {\n\tport := *opts.RPCPort.Value()\n\tif l, err := net.Listen(\"tcp\", fmt.Sprintf(\"127.0.0.1:%d\", port)); err != nil {\n\t\treturn fmt.Errorf(\"port %d unavailable: %w\", port, err)\n\t} else {\n\t\tl.Close()\n\t}\n}","typeGuard":null,"tryCatchPattern":"cb, err := server.Initialize(opts)\nif err != nil && strings.Contains(err.Error(), \"starting gRPC server\") {\n\t// retry with a random port instead of the requested one\n\topts.RPCPort = nil\n\tcb, err = server.Initialize(opts)\n}\nif err != nil {\n\treturn err\n}","preventionTips":["Prefer letting skaffold pick a random port (omit --rpc-port) unless a client needs a fixed one","Check for stale skaffold processes (ps aux | grep skaffold) before rerunning","Use ports >= 1024 to avoid privilege issues","Coordinate fixed RPC ports per developer/machine to avoid collisions"],"tags":["grpc","network","port-in-use","skaffold"],"backgroundTag":"port-already-in-use","analyzedSha":"a1189de023efc32d4b8e11f395acc678aa555011","analyzedAt":"2026-09-05T12:09:27.064Z","contentChangedAt":"2026-09-05T12:09:27.064Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}