jeessy2/ddns-go · critical
监听端口发生异常, 请检查端口是否被占用! %s
Error message
监听端口发生异常, 请检查端口是否被占用! %s
What it means
runWebServer binds the HTTP listener with net.Listen("tcp", *listen). If binding fails (port already in use, permission denied, invalid address), it returns this error telling the user to check whether the port is occupied. The underlying OS error is appended via %s.
Source
Thrown at main.go:211
// 启动静态文件服务
http.HandleFunc("/static/", web.AuthAssert(staticFsFunc))
http.HandleFunc("/favicon.ico", web.AuthAssert(faviconFsFunc))
http.HandleFunc("/login", web.AuthAssert(web.Login))
http.HandleFunc("/loginFunc", web.AuthAssert(web.LoginFunc))
http.HandleFunc("/", web.Auth(web.Writing))
http.HandleFunc("/save", web.Auth(web.Save))
http.HandleFunc("/setLang", web.Auth(web.SetLang))
http.HandleFunc("/logs", web.Auth(web.Logs))
http.HandleFunc("/clearLog", web.Auth(web.ClearLog))
http.HandleFunc("/webhookTest", web.Auth(web.WebhookTest))
http.HandleFunc("/logout", web.Auth(web.Logout))
util.Log("监听 %s", *listen)
l, err := net.Listen("tcp", *listen)
if err != nil {
return errors.New(util.LogStr("监听端口发生异常, 请检查端口是否被占用! %s", err))
}
return http.Serve(l, nil)
}
// 以守护/分离进程方式运行(Unix 使用 setsid,Windows 使用 DETACHED_PROCESS)
func runAsDaemon() error {
exe, err := os.Executable()
if err != nil {
return err
}
// 过滤掉 -d 参数
args := make([]string, 0, len(os.Args))
args = append(args, exe)
for i := 1; i < len(os.Args); i++ {
if os.Args[i] == "-d" {
continueView on GitHub (pinned to 5874c2e666)
Solutions
- Find and stop the process occupying the port: lsof -i :PORT or ss -tlnp, then kill it or change -listen to a free port
- Run with elevated privileges if binding a privileged port, or use a port >= 1024
- Check the -listen value for typos/invalid address syntax (e.g. ':8080' or '0.0.0.0:8080')
- Read the wrapped OS error after the '!' for the precise cause (address in use vs permission denied)
Example fix
// before ./app -listen :8080 # fails: port in use // after ss -tlnp | grep 8080 # find offender ./app -listen :8081 # or kill the offending process
Defensive patterns
Strategy: validation
Validate before calling
// pre-flight check before starting the server
func portFree(addr string) bool {
l, err := net.Listen("tcp", addr)
if err != nil {
return false
}
l.Close()
return true
} Type guard
null
Try / catch
l, err := net.Listen("tcp", *listen)
if err != nil {
return errors.New(util.LogStr("监听端口发生异常, 请检查端口是否被占用! %s", err))
}
// caller:
if err := runWebServer(); err != nil {
if strings.Contains(err.Error(), "监听端口发生异常") {
// instruct user to free the port or change -listen
}
} Prevention
- Before startup, run ss -tlnp / lsof -i :PORT to confirm the port is free
- Use ports >= 1024 to avoid permission problems
- Make the listen address configurable and document valid formats
- Avoid running duplicate instances; use a PID file or systemd unit to enforce single instance
When it happens
Trigger: Starting the app with -listen pointing to a port already bound by another process; binding to a privileged port (<1024) without root; malformed listen address; IPv6 address not available on the host.
Common situations: Two instances of the app running simultaneously; another service (nginx, previous un-killed process) occupies the port; Docker/container lacks port binding permission; typo in the listen flag.
Related errors
AI-assisted analysis of jeessy2/ddns-go@5874c2e666 (2026-09-03).
Data as JSON: /api/errors/3702725fedfa60f6.
Report an issue: GitHub.