{"record":{"id":"b0677bcd35a76ced","repo":"yudai/gotty","slug":"failed-to-listen-at-s","errorCode":null,"errorMessage":"failed to listen at `%s`","messagePattern":"failed to listen at `(.+?)`","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/server.go","lineNumber":122,"sourceCode":"\tsrv, err := server.setupHTTPServer(handlers)\n\tif err != nil {\n\t\treturn errors.Wrapf(err, \"failed to setup an HTTP server\")\n\t}\n\n\tif server.options.PermitWrite {\n\t\tlog.Printf(\"Permitting clients to write input to the PTY.\")\n\t}\n\tif server.options.Once {\n\t\tlog.Printf(\"Once option is provided, accepting only one client\")\n\t}\n\n\tif server.options.Port == \"0\" {\n\t\tlog.Printf(\"Port number configured to `0`, choosing a random port\")\n\t}\n\thostPort := net.JoinHostPort(server.options.Address, server.options.Port)\n\tlistener, err := net.Listen(\"tcp\", hostPort)\n\tif err != nil {\n\t\treturn errors.Wrapf(err, \"failed to listen at `%s`\", hostPort)\n\t}\n\n\tscheme := \"http\"\n\tif server.options.EnableTLS {\n\t\tscheme = \"https\"\n\t}\n\thost, port, _ := net.SplitHostPort(listener.Addr().String())\n\tlog.Printf(\"HTTP server is listening at: %s\", scheme+\"://\"+host+\":\"+port+path)\n\tif server.options.Address == \"0.0.0.0\" {\n\t\tfor _, address := range listAddresses() {\n\t\t\tlog.Printf(\"Alternative URL: %s\", scheme+\"://\"+address+\":\"+port+path)\n\t\t}\n\t}\n\n\tsrvErr := make(chan error, 1)\n\tgo func() {\n\t\tif server.options.EnableTLS {\n\t\t\tcrtFile := homedir.Expand(server.options.TLSCrtFile)","sourceCodeStart":104,"sourceCodeEnd":140,"githubUrl":"https://github.com/yudai/gotty/blob/a080c85cbc59226c94c6941ad8c395232d72d517/server/server.go#L104-L140","documentation":"Run() calls net.Listen(\"tcp\", address:port) to bind the listener. If the OS refuses the bind (port in use, permission denied, invalid address), the error is wrapped with the host:port that failed. GoTTY exits and no server is started.","triggerScenarios":"Calling Run() when options.Port is already bound by another process, below 1024 without privileges, or options.Address is not a local IP/hostname.","commonSituations":"Another GoTTY or web server already on port 8080; running in a container without the port mapped/allowed; address typo like 0.0.0.0 vs an unassigned interface IP; port 80/443 without root (or setcap).","solutions":["Choose a free port (or port \"0\" to let GoTTY pick a random one)","Stop the process occupying the port (lsof -i :PORT / netstat)","Use address 0.0.0.0 or 127.0.0.1 instead of an unassigned interface address","For privileged ports, run with root/cap_net_bind_service or use a high port"],"exampleFix":"// before\nport = \"80\"\n// after\nport = \"8080\"","handlingStrategy":"retry","validationCode":"func portFree(addr, port string) bool {\n    ln, err := net.Listen(\"tcp\", net.JoinHostPort(addr, port))\n    if err != nil { return false }\n    ln.Close()\n    return true\n}","typeGuard":null,"tryCatchPattern":"if err := srv.Run(ctx); err != nil {\n    var nerr *net.OpError\n    if errors.As(err, &nerr) {\n        // address already in use / permission denied — pick another port\n    }\n}","preventionTips":["Use port \"0\" or an ephemeral high port in shared environments","Check port availability before starting; avoid fixed privileged ports","Bind 0.0.0.0/127.0.0.1 rather than specific interface IPs"],"tags":["network","tcp","listen"],"backgroundTag":"address-already-in-use","analyzedSha":"a080c85cbc59226c94c6941ad8c395232d72d517","analyzedAt":"2026-09-02T16:42:38.150Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T21:17:11.164Z"}