micro/go-micro · error
already listening on ${addr}
Error message
already listening on ${addr} What it means
Listen refuses to bind an address that already has a memory listener registered in the same process, returning 'already listening on <addr>'. The in-memory transport keys listeners by the exact normalized host:port, so two Listen calls with the same (normalized) address collide.
Source
Thrown at transport/memory.go:254
return nil, err
}
addr, err = maddr.Extract(host)
if err != nil {
return nil, err
}
// if zero port then randomly assign one
if len(port) > 0 && port == "0" {
i := rand.Intn(20000)
port = fmt.Sprintf("%d", 10000+i)
}
// set addr with port
addr = mnet.HostPort(addr, port)
if _, ok := m.listeners[addr]; ok {
return nil, errors.New("already listening on " + addr)
}
listener := &memoryListener{
lopts: options,
topts: m.opts,
addr: addr,
conn: make(chan *memorySocket),
exit: make(chan bool),
ctx: m.opts.Context,
}
m.listeners[addr] = listener
return listener, nil
}
func (m *memoryTransport) Init(opts ...Option) error {
for _, o := range opts {View on GitHub (pinned to 24529f1404)
Solutions
- Close the existing listener before Listen on the same address, or pick a distinct port (or ":0" for an ephemeral port)
- Track created listeners (map keyed by addr) so setup code never calls Listen twice
- Check the error — it names the colliding address — and correct the config so each server has a unique host:port
Example fix
// before
m.Listen("127.0.0.1:8080")
m.Listen("127.0.0.1:8080") // already listening on 127.0.0.1:8080
// after
l, err := m.Listen("127.0.0.1:8080")
if err == nil { defer l.Close() }
l2, err := m.Listen("127.0.0.1:8081") // distinct addr Defensive patterns
Strategy: validation
Validate before calling
if _, ok := listeners[addr]; ok {
return fmt.Errorf("already listening on %s", addr)
} Try / catch
l, err := m.Listen(addr)
if err != nil && strings.HasPrefix(err.Error(), "already listening on ") {
// reuse existing listener or choose another port
} Prevention
- Track your listeners and Close before re-Listen
- Use ":0" ephemeral ports in tests
- Keep a registry of ports per test to avoid cross-test collisions
When it happens
Trigger: Calling Listen twice on the same addr string; two components configured with the same fixed port; Listen on 'host:0' resolving to the same port as an existing listener (rare but possible).
Common situations: Starting a server twice due to duplicate init code or a test suite running setup twice; multiple services in one binary configured with the same port; forgetting a previous Close when reusing addresses in tests.
Related errors
- could not dial ${addr}
- connection error
- addr (nats subject) must not be empty
- addr (nats subject) must not contain space characters
- failed request
AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01).
Data as JSON: /api/errors/d5c2b6a92b37ca03.
Report an issue: GitHub.