gohugoio/hugo · error
server startup failed
Error message
server startup failed: %s
What it means
`createServerPorts` calls `net.Listen("tcp", host:port)` for the configured port. If that fails AND the user set `--port` explicitly, Hugo refuses to fall back and wraps the listen error as `server startup failed`. The explicit-port contract is: the user meant this port, so do not silently relocate.
Solutions
- Free the port: find and stop the occupying process (`lsof -i :PORT`).
- Choose a different `--port` that is known free.
- Use a non-privileged port (>1024) unless running as root with explicit need.
- Drop the explicit `--port` to let Hugo auto-select an alternative.
Example fix
// before // $ hugo server --port=1313 (already in use) // after // $ lsof -ti:1313 | xargs kill ; hugo server --port=1313
Defensive patterns
Strategy: validation
Validate before calling
import (
"net"
"strconv"
)
func validatePortFree(host string, port int) error {
ln, err := net.Listen("tcp", net.JoinHostPort(host, strconv.Itoa(port)))
if err != nil { return err }
ln.Close()
return nil
} Type guard
null
Try / catch
// If the pinned port is busy, free it or let Hugo auto-select by
// dropping the explicit --port.
if err := cmd.Execute(); err != nil {
if strings.Contains(err.Error(), "server startup failed") { /* free port or drop --port */ }
} Prevention
- Stop previous `hugo server`/dev processes before reusing a port.
- Avoid privileged ports (<1024) as a non-root user.
- Drop the explicit `--port` to let Hugo auto-select a free one.
When it happens
Trigger: Fires on the first port (`i == 0`) when `--port` was changed on the CLI and `net.Listen` returns an error — typically `bind: address already in use` or `bind: permission denied` (privileged port).
Common situations: Another process (often a previous `hugo server` or a dev server) holds the chosen port; requesting a privileged port `<1024` as a non-root user; a port blocked by firewall/SELinux.
Related errors
- unable to find alternative port to use
- failed to split baseURL hostport
- --appendPort=false not supported when in multihost mode
- cannot use --renderToMemory with --destination
- failed to clone
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/19d4c96d7a846ec1.
Report an issue: GitHub.
Appendix: source
Thrown at commands/server.go:774
c.withConf(func(conf *commonConfig) {
isMultihost := conf.configs.IsMultihost
c.serverPorts = make([]serverPortListener, 1)
if isMultihost {
if !c.serverAppend {
cerr = errors.New("--appendPort=false not supported when in multihost mode")
return
}
c.serverPorts = make([]serverPortListener, len(conf.configs.Languages))
}
currentServerPort := c.serverPort
for i := range c.serverPorts {
l, err := net.Listen("tcp", net.JoinHostPort(c.serverInterface, strconv.Itoa(currentServerPort)))
if err == nil {
c.serverPorts[i] = serverPortListener{ln: l, p: currentServerPort}
} else {
if i == 0 && flags.Changed("port") {
// port set explicitly by user -- he/she probably meant it!
cerr = fmt.Errorf("server startup failed: %s", err)
return
}
c.r.Println("port", currentServerPort, "already in use, attempting to use an available port")
l, sp, err := helpers.TCPListen()
if err != nil {
cerr = fmt.Errorf("unable to find alternative port to use: %s", err)
return
}
c.serverPorts[i] = serverPortListener{ln: l, p: sp.Port}
}
currentServerPort = c.serverPorts[i].p + 1
}
})
return cerr
}
View on GitHub (pinned to 52c9bd7908)