grpc/grpc-go · warning

duplicated name

Error message

duplicated name

What it means

errDuplicatedName (service_config.go:129) is returned while parsing a service config when two entries in methodConfig[].name[] resolve to the same path. generatePath() builds "/<service>/<method>" (or "/<service>" for service-wide), and the parser keys MethodConfigs by that path; a duplicate collision at service_config.go:250-251 aborts the parse via serviceconfig.ParseResult.Err. This is a client-side parse error of the service config (from name resolution / default-service-config), not a runtime RPC error.

Solutions

  1. Inspect the full service config JSON and de-duplicate the methodConfig[].name entries so each /Service/Method (and each /Service) path appears exactly once.
  2. Enable gRPC client logging at WARNING to capture the 'grpc: error unmarshalling service config ... methodConfig[N]' line, which names the offending index.
  3. If the config is fetched from a name resolver (DNS/xDS), correct it at the source; if set via grpc.WithDefaultServiceConfig, fix the embedded string.
  4. Validate the config with a small parser/lint rule that no two names collapse to the same path before deploying.

Example fix

// before
"methodConfig": [
  { "name": [{"service":"foo.Bar","method":"Echo"}], "timeout": "1s" },
  { "name": [{"service":"foo.Bar","method":"Echo"}], "retryPolicy": {...} }
]

// after
"methodConfig": [
  { "name": [{"service":"foo.Bar","method":"Echo"}], "timeout": "1s", "retryPolicy": {...} }
]
Defensive patterns

Strategy: validation

Validate before calling

// Validate a service config for duplicate method paths before installing it.
func validateServiceConfig(cfg string) error {
    var sc struct {
        MethodConfig []struct {
            Name []struct{ Service, Method string } `json:"name"`
        } `json:"methodConfig"`
    }
    if err := json.Unmarshal([]byte(cfg), &sc); err != nil {
        return err
    }
    seen := map[string]struct{}{}
    for _, mc := range sc.MethodConfig {
        for _, n := range mc.Name {
            path := "/" + n.Service + "/" + n.Method
            if n.Method == "" {
                path = "/" + n.Service
            }
            if _, dup := seen[path]; dup {
                return fmt.Errorf("duplicated name: %s", path)
            }
            seen[path] = struct{}{}
        }
    }
    return nil
}

Try / catch

pr := serviceconfig.Parse(cfg)
if pr.Err != nil {
    if strings.Contains(pr.Err.Error(), "duplicated name") {
        // dedupe the offending methodConfig[].name entries
    }
}

Prevention

When it happens

Trigger: A service config JSON where methodConfig[].name lists the same {service, method} pair twice, or two methodConfig entries covering the same "/Service/Method" path, or two service-wide {"service":"Foo"} entries that both expand to "/Foo". Served via DNS TXT records, xDS, or grpc.WithDefaultServiceConfig.

Common situations: Hand-edited service config JSON; copy-paste of method config blocks; service config generation tools emitting overlapping name patterns; upgrading a config that used wildcards now treated as explicit.

Related errors


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

Appendix: source

Thrown at service_config.go:129

	// between 0 and maxTokens.
	//
	// This field is required and must be greater than zero.
	MaxTokens float64
	// The amount of tokens to add on each successful RPC. Typically this will
	// be some number between 0 and 1, e.g., 0.1.
	//
	// This field is required and must be greater than zero. Up to 3 decimal
	// places are supported.
	TokenRatio float64
}

type jsonName struct {
	Service string
	Method  string
}

var (
	errDuplicatedName             = errors.New("duplicated name")
	errEmptyServiceNonEmptyMethod = errors.New("cannot combine empty 'service' and non-empty 'method'")
)

func (j jsonName) generatePath() (string, error) {
	if j.Service == "" {
		if j.Method != "" {
			return "", errEmptyServiceNonEmptyMethod
		}
		return "", nil
	}
	res := "/" + j.Service + "/"
	if j.Method != "" {
		res += j.Method
	}
	return res, nil
}

// TODO(lyuxuan): delete this struct after cleaning up old service config implementation.

View on GitHub (pinned to 0c51461d27)