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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions