dapr/dapr · error

failed to start internal gRPC server: %w

Error message

failed to start internal gRPC server: %w

What it means

Returned when the internal gRPC server (used for sidecar-to-sidecar communication, e.g. service invocation between sidecars) fails to start via startGRPCInternalServer. The listener binds internalGRPCListenAddress:internalGRPCPort; failure is typically an address-in-use or invalid/unbindable listen address. Startup aborts.

Source

Thrown at pkg/runtime/runtime.go:847

	// Start HTTP Server
	err = a.startHTTPServer(ctx)
	if err != nil {
		return fmt.Errorf("failed to start HTTP server: %w", err)
	}

	if a.runtimeConfig.unixDomainSocket != "" {
		log.Info("HTTP server is running on a Unix Domain Socket")
	} else {
		log.Infof("HTTP server is running on port %v", a.runtimeConfig.httpPort)
	}

	log.Infof("The request body size parameter is: %v bytes", a.runtimeConfig.maxRequestBodySize)

	// Start internal gRPC server (used for sidecar-to-sidecar communication)
	err = a.startGRPCInternalServer(ctx, a.daprGRPCAPI)
	if err != nil {
		return fmt.Errorf("failed to start internal gRPC server: %w", err)
	}

	log.Infof("Internal gRPC server is running on %s:%d", a.runtimeConfig.internalGRPCListenAddress, a.runtimeConfig.internalGRPCPort)

	if err := a.initActors(ctx); err != nil {
		return fmt.Errorf("failed to initialize actors: %w", err)
	}

	// MCPServers register workflow actors and must run after initActors.
	if err := a.loadMCPServers(ctx); err != nil {
		return fmt.Errorf("failed to load mcpservers: %s", err)
	}
	if err := a.flushOutstandingMCPServers(ctx); err != nil {
		return err
	}

	a.runtimeConfig.outboundHealthz.AddTarget("app").Ready()

View on GitHub (pinned to 74ad417027)

Solutions

  1. Read the wrapped error to identify bind vs address error
  2. Free or change the internal port via --dapr-internal-grpc-port so it does not collide with the API gRPC/HTTP ports
  3. Verify internalGRPCListenAddress (defaults to loopback) is assigned to the container/host when overridden
  4. Check the log line 'Internal gRPC server is running on ...' on a healthy run to know the expected bind target

Example fix

# before: internal port collides with API gRPC port
daprd --app-id myapp --dapr-internal-grpc-port 50001
# after
daprd --app-id myapp --dapr-internal-grpc-port 50010
Defensive patterns

Strategy: validation

Validate before calling

func checkInternalBind(addr string, port int) error {
    ln, err := net.Listen("tcp", net.JoinHostPort(addr, strconv.Itoa(port)))
    if err != nil { return fmt.Errorf("internal gRPC bind %s:%d failed: %w", addr, port, err) }
    ln.Close()
    return nil
}

Type guard

func isInternalGRPCStartErr(err error) bool {
    return err != nil && strings.HasPrefix(err.Error(), "failed to start internal gRPC server:")
}

Prevention

When it happens

Trigger: The internal gRPC port (--dapr-internal-grpc-port) already bound; the internal listen address set to an IP not present on the pod/host; two daprd processes sharing the same internal port.

Common situations: Overlapping ports when several sidecars run on one node or in one container; custom internal listen address configured in Helm/annotations that does not exist on the interface; port collisions after port-range remapping in compose files.

Related errors


AI-assisted analysis of dapr/dapr@74ad417027 (2026-08-16). Data as JSON: /api/errors/2b47bf48c657b193. Report an issue: GitHub.