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
- Read the wrapped error to identify bind vs address error
- Free or change the internal port via --dapr-internal-grpc-port so it does not collide with the API gRPC/HTTP ports
- Verify internalGRPCListenAddress (defaults to loopback) is assigned to the container/host when overridden
- 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
- Give the internal gRPC port its own value, never equal to the API gRPC or HTTP port
- When overriding the internal listen address, verify the IP exists on the interface first
- In multi-sidecar hosts/compose files, reserve a contiguous block per app
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
- failed to start API gRPC server: %w
- could not listen on port %d: %w
- failed to start HTTP server: %w
- could not listen on port %d: %w
- failed to listen on %s: %w
AI-assisted analysis of dapr/dapr@74ad417027 (2026-08-16).
Data as JSON: /api/errors/2b47bf48c657b193.
Report an issue: GitHub.