服务在本地跑得好好的,推到测试环境启动就报 listen tcp: invalid address。端口没被占,防火墙也放行了,看了一眼配置只觉得没毛病。
invalid address 指的是地址字符串
它跟 address already in use 完全不同。后者是端口被占,前者是地址根本解析不了。常见写法把协议头带进去了,比如 http://0.0.0.0:8080,或者环境变量末尾多了空格、引号。程序拿到这串字符去解析,直接失败。
addr := os.Getenv("LISTEN_ADDR"); ln, err := net.Listen("tcp", addr)其他场景也会出现
ping 报 invalid address,多半是域名解析失败或者 IPv6 地址少了方括号。C 程序里打印一个野指针,也会看到 invalid address 之类的提示。socket 编程里 bind 传的地址长度不对,错误信息同样模糊。先分清是网络层还是程序层,别一上来就改防火墙。
排查顺序
- 打印原始值:把地址变量原样输出,看有没有多余字符
- 校验格式:Go 用 net.ParseIP,C 用 inet_pton,解析失败就别往下走
- IPv6 写法:监听所有地址写 [::]:8080,不是 ::8080
- 配置来源:env 文件不要给值加引号,容器里注意换行符
端口占用长什么样
address already in use 会明确说端口冲突,lsof -i:8080 或 netstat -ano 能找到进程。invalid address 则是连绑定都没走到。两者别混着查,方向不一样。
容器和配置中心容易埋雷
K8s 的 env 值从 ConfigMap 注入时,末尾可能带一个换行,肉眼看不见。Docker 的 command 写成数组和字符串,引号处理也不同。上线前在启动日志里打一行地址原文,长度和字符都打出来,比猜快得多。
遇到这类报错,先把字符串原样打出来。多半是一眼能看出的空格、协议头或者括号问题。