GoogleContainerTools/skaffold · error
starting HTTP server: %w
Error message
starting HTTP server: %w
What it means
server.Initialize wraps failures from newHTTPServer — which serves the HTTP variant of the Skaffold API and proxies to the gRPC port — as 'starting HTTP server: %w'. This happens after the gRPC server started successfully, when --rpc-http-port was requested and its listener could not be created.
Source
Thrown at pkg/skaffold/server/server.go:165
logFileErr := event.SaveEventsToFile(opts.EventLogFile)
if logFileErr != nil {
errStr += fmt.Sprintf("event log file error: %s\n", logFileErr.Error())
}
v2EventLogFile := fmt.Sprintf(`%s.v2`, opts.EventLogFile)
logFileV2Err := eventV2.SaveEventsToFile(v2EventLogFile)
if logFileV2Err != nil {
errStr += fmt.Sprintf("eventV2 log file error: %s\n", logFileV2Err.Error())
}
}
// Save logs from current run to file
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()View on GitHub (pinned to a1189de023)
Solutions
- Free the HTTP port (lsof -i :PORT / ss -ltnp) and stop the conflicting process.
- Pick a different port via --rpc-http-port, or drop the flag entirely (skaffold then only runs the gRPC API on a chosen port).
- Note the gRPC server is already up when this fires: the returned shutdown callback will tear it down; simply retry after fixing the HTTP port.
- Ensure the port is unprivileged or the process has permission to bind it.
Example fix
// before skaffold dev --rpc-http-port 50052 // in use // after skaffold dev --rpc-http-port 50053 # or omit the flag: skaffold dev --rpc-port 50051
Defensive patterns
Strategy: retry
Validate before calling
if opts.RPCHTTPPort.Value() != nil {
port := *opts.RPCHTTPPort.Value()
l, err := net.Listen("tcp", fmt.Sprintf("127.0.0.1:%d", port))
if err != nil {
return fmt.Errorf("http port %d unavailable: %w", port, err)
}
l.Close()
} Try / catch
cb, err := server.Initialize(opts)
if err != nil && strings.Contains(err.Error(), "starting HTTP server") {
// give up the fixed HTTP port and retry without it (gRPC API still available)
opts.RPCHTTPPort = nil
cb, err = server.Initialize(opts)
}
if err != nil {
return err
} Prevention
- Choose an --rpc-http-port distinct from the --rpc-port and other local servers
- Verify the port is free with ss -ltnp or lsof before launching
- Omit --rpc-http-port when only the gRPC API is needed
- Use unprivileged ports in containers/CI
When it happens
Trigger: Calling Initialize(opts) with a non-nil opts.RPCHTTPPort and newHTTPServer(port, grpcPort) fails at listenPort: the requested HTTP port is occupied, privileged, or otherwise unbindable.
Common situations: Another skaffold run or an IDE plugin already holds the --rpc-http-port; the port collides with a locally running web server; container environments restricting port binding.
Related errors
- starting gRPC server: %w
- INIT_DOCKER_NETWORK_CONTAINER_DOES_NOT_EXIST
- one platform returned an non-success response: %d
- failed to download manifest from %s, err : %w
- getting latest and current skaffold versions: %w
AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05).
Data as JSON: /api/errors/4e42ed56ade12c4b.
Report an issue: GitHub.