micro/go-micro · error

could not dial ${addr}

Error message

could not dial ${addr}

What it means

The in-memory transport only allows dialing addresses that have a registered listener in the same process. Dial looks up m.listeners[addr]; if nothing is listening on that exact address string it returns 'could not dial <addr>'. Because it's process-local, a mismatched address string is the usual culprit.

Source

Thrown at transport/memory.go:188

				exit:    c.exit,
				ssend:   c.ssend,
				srecv:   c.srecv,
				local:   c.Remote(),
				remote:  c.Local(),
				timeout: m.topts.Timeout,
				ctx:     m.topts.Context,
			})
		}
	}
}

func (m *memoryTransport) Dial(addr string, opts ...DialOption) (Client, error) {
	m.RLock()
	defer m.RUnlock()

	listener, ok := m.listeners[addr]
	if !ok {
		return nil, errors.New("could not dial " + addr)
	}

	var options DialOptions
	for _, o := range opts {
		o(&options)
	}

	creader, swriter := io.Pipe()
	sreader, cwriter := io.Pipe()

	client := &memoryClient{
		&memorySocket{
			server: false,
			csend:  gob.NewEncoder(cwriter),
			crecv:  gob.NewDecoder(creader),
			ssend:  gob.NewEncoder(swriter),
			srecv:  gob.NewDecoder(sreader), exit: make(chan bool),
			lexit:   listener.exit,

View on GitHub (pinned to 24529f1404)

Solutions

  1. Ensure Listen(addr) completed and use the address it returns (it resolves port 0 and adds missing ports) as the Dial target
  2. Make host/port strings match exactly after HostPort normalization (same host, same resolved port)
  3. In tests, capture the listener's addr via server-side socket or the returned listener before dialing; add synchronization so Listen happens before Dial

Example fix

// before
server.Listen(":0") // binds random port
c.Dial("localhost:0") // could not dial localhost:0
// after
l, err := server.Listen(":0")
addr := l.Addr() // actual resolved host:port
c.Dial(addr)
Defensive patterns

Strategy: validation

Validate before calling

l, err := m.Listen(":0")
if err != nil { return err }
addr := l.Addr() // use this exact addr for Dial

Try / catch

c, err := m.Dial(addr)
if err != nil && strings.HasPrefix(err.Error(), "could not dial ") {
	// re-check listener is up, use listener.Addr()
}

Prevention

When it happens

Trigger: transport.Dial(addr) before the corresponding server called Listen(addr); address strings that differ after Listen normalized them via mnet.HostPort (e.g. '127.0.0.1:0' vs the resolved '127.0.0.1:54321', or 'localhost:8080' vs '127.0.0.1:8080').

Common situations: Tests that dial before the listener goroutine finishes Listen; using the configured address instead of the actual bound address returned by Listen; missing ':' port or hostname aliasing mismatch.

Related errors


AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01). Data as JSON: /api/errors/092e4eb703f7a961. Report an issue: GitHub.