{"record":{"id":"179463956c895221","repo":"v2fly/v2ray-core","slug":"invalid-listen-address","errorCode":null,"errorMessage":"invalid listen address ","messagePattern":"invalid listen address ","errorType":"panic","errorClass":"errors.Error","httpStatus":null,"severity":"critical","filePath":"transport/internet/tlsmirror/mirrorenrollment/roundtripperenrollmentconfirmation/server.go","lineNumber":47,"sourceCode":"}\n\ntype Server struct {\n\tconfig              *ServerConfig\n\tctx                 context.Context\n\tenrollmentProcessor tlsmirror.ConnectionEnrollmentConfirmationProcessor\n\trttServer           request.RoundTripperServer\n}\n\nfunc (s *Server) OnConnectionEnrollmentConfirmationServerInstanceConfigReady(config tlsmirror.ConnectionEnrollmentConfirmationServerInstanceConfig) {\n\ts.enrollmentProcessor = config.EnrollmentProcessor\n}\n\nfunc (s *Server) Listen(ctx context.Context) (v2net.Listener, error) {\n\ttransportEnvironment := envctx.EnvironmentFromContext(s.ctx).(environment.TransportEnvironment)\n\tlistener := transportEnvironment.Listener()\n\taddr, err := v2net.ParseDestination(s.config.Listen)\n\tif err != nil {\n\t\tpanic(newError(\"invalid listen address \" + s.config.Listen).Base(err).AtError())\n\t}\n\tnetaddr := &net.TCPAddr{IP: addr.Address.IP(), Port: int(addr.Port)}\n\tl, err := listener.Listen(s.ctx, netaddr, nil)\n\tif err != nil {\n\t\tpanic(newError(\"failed to listen on \" + s.config.Listen).Base(err).AtError())\n\t}\n\treturn l, nil\n}\n\nfunc (s *Server) OnRoundTrip(ctx context.Context, req request.Request, opts ...request.RoundTripperOption) (resp request.Response, err error) {\n\tenrollmentReq := &tlsmirror.EnrollmentConfirmationReq{}\n\terr = proto.Unmarshal(req.Data, enrollmentReq)\n\tif err != nil {\n\t\treturn request.Response{}, newError(\"failed to unmarshal enrollment confirmation request\").Base(err).AtError()\n\t}\n\tenrollmentResp, err := s.enrollmentProcessor.VerifyConnectionEnrollment(enrollmentReq)\n\tif err != nil {\n\t\treturn request.Response{}, newError(\"failed to process enrollment confirmation request\").Base(err).AtError()","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/v2fly/v2ray-core/blob/db1291416195df07b287d79d8b9afe451c186c33/transport/internet/tlsmirror/mirrorenrollment/roundtripperenrollmentconfirmation/server.go#L29-L65","documentation":"This panic is raised in the TLS-mirror enrollment-confirmation server's Listen() when v2net.ParseDestination fails to parse the configured listen string (ServerConfig.listen, field 3 of the roundtripperenrollmentconfirmation ServerConfig proto). ParseDestination (common/net/destination.go:30) only accepts forms like 'tcp:1.2.3.4:5678', 'udp:host:port', 'unix:/path', or a bare 'host:port' (defaulting to TCP); anything else — missing port, non-numeric port, port out of range, malformed IPv6 — returns an error, and this code converts it into a process-killing panic with AtError severity.","triggerScenarios":"Setting ServerConfig.listen to a bare IP or hostname with no port ('127.0.0.1'); a port that is not a number or exceeds 65535 ('tcp:0.0.0.0:99999'); IPv6 without brackets or the tcp: prefix ('::1:443'); leaving the field empty-ish with stray whitespace; JSON/TOML config typos where the value is a number or an object rather than the expected string.","commonSituations":"First-time setup of the tlsmirror enrollment confirmation component where users copy an address format from another tool (e.g. 'localhost' alone, or a URL like 'tcp://host:port' with a double slash); config generated by scripts that concatenate host and port incorrectly; version migrations where the listen key was renamed and silently ends up zero-valued/empty.","solutions":["Fix the listen string to the exact expected format 'tcp:IP:PORT' (e.g. 'tcp:127.0.0.1:9443'); note the prefix has a single colon, no slashes.","Validate the address before startup with v2net.ParseDestination in your config loader (or a unit test over shipped configs) so errors surface as config errors, not panics.","For IPv6, use bracketed host: 'tcp:[::1]:9443'.","If you meant a Unix socket, use the 'unix:/path/to/socket' form — but be aware this code then builds a net.TCPAddr from addr.Address.IP(), so for this server stick to tcp with a literal IP."],"exampleFix":"// before (config)\n{\n  \"listen\": \"127.0.0.1\"   // ParseDestination fails: missing port -> panic\n}\n\n// after\n{\n  \"listen\": \"tcp:127.0.0.1:9443\"\n}","handlingStrategy":"validation","validationCode":"// validate the enrollment-confirmation listen string before starting the server:\ndest, err := net.ParseDestination(cfg.Listen)\nif err != nil {\n    return fmt.Errorf(\"invalid enrollment listen address %q: %w\", cfg.Listen, err)\n}\nif dest.Network != net.Network_TCP {\n    return fmt.Errorf(\"enrollment listen must be tcp, got %q\", cfg.Listen)\n}\n// optional: reject hostnames, this server binds a literal TCPAddr\nif !dest.Address.IsIP() {\n    return fmt.Errorf(\"enrollment listen must use a literal IP, got %q\", dest.Address.String())\n}","typeGuard":"func isValidListenAddress(s string) bool {\n    d, err := net.ParseDestination(s)\n    return err == nil && d.Network == net.Network_TCP && d.Address.IsIP() && d.Port > 0\n}","tryCatchPattern":"// wrap server startup so a bad config surfaces as an error, not a crash:\nfunc startEnrollmentServer(s *rec.Server) (err error) {\n    defer func() {\n        if r := recover(); r != nil {\n            err = fmt.Errorf(\"enrollment server startup failed: %v\", r)\n        }\n    }()\n    l, err := s.Listen(ctx)\n    if err != nil {\n        return err\n    }\n    _ = l // serve...\n    return nil\n}","preventionTips":["Use the exact format 'tcp:IP:PORT' (single colon prefix, no scheme slashes) for the listen field.","Add a config-validation pass (or unit test) that runs net.ParseDestination over every listen value in shipped configs.","Bracket IPv6 hosts: 'tcp:[::1]:9443'.","Prefer literal IPs over hostnames since this component binds a net.TCPAddr directly."],"tags":["tlsmirror","listen","config","parse","panic","startup"],"backgroundTag":null,"analyzedSha":"db1291416195df07b287d79d8b9afe451c186c33","analyzedAt":"2026-08-15T14:51:20.977Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}