grpc/grpc-go · error

failed to push new configuration

Error message

failed to push new configuration %v to child %q: %v

What it means

After building a ClientConnState for a child, cluster_manager calls bg.UpdateClientConnState (clustermanager.go:136-146). If the underlying child balancer returns a non-nil error, cluster_manager wraps it (including the original config that failed) and installs an error picker for that one child. Other children keep serving RPCs.

Solutions

  1. Read the wrapped error fully: it includes both the original config (first %v) and the underlying child error (last %v).
  2. Fix the underlying child issue surfaced by the inner error.
  3. Remember only RPCs routed to this child fail; isolate debugging to that child's config.
Defensive patterns

Strategy: try-catch

Try / catch

// cluster_manager returns the last child error; the inner error has the root cause.
if err := cm.UpdateClientConnState(state); err != nil {
    if strings.Contains(err.Error(), "failed to push new configuration") {
        // extract child name from message, read inner %v for the actual cause
    }
}

Prevention

When it happens

Trigger: The child balancer's UpdateClientConnState rejects the config (its own validation failure, bad resolver state, missing xDS client, etc.) while a new configuration is being applied.

Common situations: Child policy config that fails the child's own validation (e.g. weighted_round_robin rejecting a backend with no metadata); transient xDS client state issues; resolver state missing required attributes; version mismatch between parent expectations and child behavior.

Related errors


AI-assisted analysis of grpc/grpc-go@0c51461d27 (2026-08-11). Data as JSON: /api/errors/4ffa2b4e385e2d8b. Report an issue: GitHub.

Appendix: source

Thrown at internal/xds/balancer/clustermanager/clustermanager.go:144

				// new child policy.
				lbCfg, err = balancergroup.ParseConfig(cfgJSON)
				if err != nil {
					retErr = fmt.Errorf("failed to parse load balancing policy for child %q: %v", childName, err)
					b.setErrorPickerForChild(childName, retErr)
					continue
				}
			}
		}

		if err := b.bg.UpdateClientConnState(childName, balancer.ClientConnState{
			ResolverState: resolver.State{
				Endpoints:     endpointsSplit[childName],
				ServiceConfig: s.ResolverState.ServiceConfig,
				Attributes:    s.ResolverState.Attributes,
			},
			BalancerConfig: lbCfg,
		}); err != nil {
			retErr = fmt.Errorf("failed to push new configuration %v to child %q: %v", childCfg.ChildPolicy.Config, childName, err)
			b.setErrorPickerForChild(childName, retErr)
		}

		// Picker update is sent to the parent ClientConn only after the
		// new child policy returns a picker. So, there is no need to
		// set needUpdateStateOnResume to true here.
	}

	b.children = newConfig.Children

	// If multiple sub-balancers run into errors, we will return only the last
	// one, which is still good enough, since the grpc channel will anyways
	// return this error as balancer.ErrBadResolver to the name resolver,
	// resulting in re-resolution attempts.
	return retErr

	// Adding or removing a sub-balancer will result in the
	// needUpdateStateOnResume bit to true which results in a picker update once

View on GitHub (pinned to 0c51461d27)