Skip to content

fix(server): bind errors on privileged ports silently swallowed — server appears started but SSH/HTTP never bind #805

@dvrd

Description

@dvrd

Summary

When a server is configured to listen on a privileged port (e.g. SSH on :22, HTTP on :80) but the process lacks the required capability, net.Listen fails immediately with EACCES. However the process does not exit and no error is logged.

Root cause

In Start() (cmd/soft/serve/server.go:115):

errg, _ := errgroup.WithContext(s.ctx)  // derived context is discarded

errg.Go(func() error {
    if err := s.SSHServer.ListenAndServe(); !errors.Is(err, ssh.ErrServerClosed) {
        return err  // EACCES returned here
    }
    return nil
})

errg.Go(func() error {
    // HTTP server runs successfully — blocks here forever
    return s.HTTPServer.ListenAndServe()
})

return errg.Wait()  // blocks forever because HTTP goroutine never exits

The SSH goroutine fails immediately and returns EACCES to the errgroup. The errgroup cancels its derived context — but the derived context was discarded (_), so no goroutine reacts to the cancellation. The HTTP goroutine (and git daemon) keep running. errg.Wait() blocks indefinitely waiting for them. s.Start() never returns. The caller never receives the error.

Fix

Pre-bind all net.Listeners synchronously in Start() before launching any goroutines. If any net.Listen call fails, return the error immediately (no goroutines have started yet). Pass each pre-bound listener to Serve(l) in the goroutines.

Closes #645

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions