grpc/grpc-go · error

error parsing observability config

Error message

error parsing observability config: %v

What it means

The observability config JSON failed to unmarshal into the internal config struct. encoding/json rejected the document before any field validation ran, so the wrapped error is a json error (syntax error, type mismatch, unknown field with DisallowUnknownFields-style failure). Emitted at config.go:114 inside unmarshalAndVerifyConfig.

Solutions

  1. Copy the config string/file out and run it through `jq .` (or `python -m json.tool`) to surface the exact JSON syntax error.
  2. Compare your keys against the documented schema: project_id, cloud_logging, cloud_monitoring, cloud_trace, labels.
  3. Remove comments (JSON has none), use double quotes, and ensure numbers (sampling_rate) are unquoted.
  4. If using a template engine, render it to a file and validate the result before pointing GRPC_GCP_OBSERVABILITY_CONFIG_FILE at it.

Example fix

// before
export GRPC_GCP_OBSERVABILITY_CONFIG='{"cloud_trace": {sampling_rate: 0.1}}'

// after
export GRPC_GCP_OBSERVABILITY_CONFIG='{"cloud_trace":{"sampling_rate":0.1}}'
Defensive patterns

Strategy: validation

Validate before calling

// Pre-validate JSON before pointing the env var at it.
func validateConfigJSON(b []byte) error {
    var c struct {
        ProjectID      string                 `json:"project_id"`
        CloudLogging   *json.RawMessage       `json:"cloud_logging"`
        CloudMonitoring *json.RawMessage      `json:"cloud_monitoring"`
        CloudTrace     *struct {
            SamplingRate float64 `json:"sampling_rate"`
        } `json:"cloud_trace"`
        Labels map[string]string `json:"labels"`
    }
    return json.Unmarshal(b, &c)
}

if err := validateConfigJSON(rawConfig); err != nil { return err }

Try / catch

if err := observability.Start(ctx); err != nil {
    if strings.Contains(err.Error(), "error parsing observability config") && !strings.Contains(err.Error(), "sampling rate") {
        // likely JSON syntax; surface the inner json error
        return fmt.Errorf("observability config JSON invalid: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Passing GRPC_GCP_OBSERVABILITY_CONFIG an invalid JSON string, or pointing GRPC_GCP_OBSERVABILITY_CONFIG_FILE at a file whose contents are not valid JSON for the config schema. Common json errors: trailing comma, single quotes, unquoted keys, a string where a number/object is expected (e.g. sampling_rate as a string).

Common situations: Hand-writing the config JSON; templating it with envsubst so '$' characters corrupt values; YAML mistakenly used instead of JSON; a stray BOM or comment block; field renamed across grpc-go versions leaving an unknown key.

Related errors


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

Appendix: source

Thrown at gcp/observability/config.go:114

		if err := validateLogEventMethod(clientRPCEvent.Methods, clientRPCEvent.Exclude); err != nil {
			return fmt.Errorf("error in clientRPCEvent method: %v", err)
		}
	}
	for _, serverRPCEvent := range config.CloudLogging.ServerRPCEvents {
		if err := validateLogEventMethod(serverRPCEvent.Methods, serverRPCEvent.Exclude); err != nil {
			return fmt.Errorf("error in serverRPCEvent method: %v", err)
		}
	}
	return nil
}

// unmarshalAndVerifyConfig unmarshals a json string representing an
// observability config into its internal go format, and also verifies the
// configuration's fields for validity.
func unmarshalAndVerifyConfig(rawJSON json.RawMessage) (*config, error) {
	var config config
	if err := json.Unmarshal(rawJSON, &config); err != nil {
		return nil, fmt.Errorf("error parsing observability config: %v", err)
	}
	if err := validateLoggingEvents(&config); err != nil {
		return nil, fmt.Errorf("error parsing observability config: %v", err)
	}
	if config.CloudTrace != nil && (config.CloudTrace.SamplingRate > 1 || config.CloudTrace.SamplingRate < 0) {
		return nil, fmt.Errorf("error parsing observability config: invalid cloud trace sampling rate %v", config.CloudTrace.SamplingRate)
	}
	logger.Infof("Parsed ObservabilityConfig: %+v", &config)
	return &config, nil
}

func parseObservabilityConfig() (*config, error) {
	if f := envconfig.ObservabilityConfigFile; f != "" {
		if envconfig.ObservabilityConfig != "" {
			logger.Warning("Ignoring GRPC_GCP_OBSERVABILITY_CONFIG and using GRPC_GCP_OBSERVABILITY_CONFIG_FILE contents.")
		}
		content, err := os.ReadFile(f)
		if err != nil {

View on GitHub (pinned to 0c51461d27)