jaegertracing/jaeger · error

max_recv_msg_size_mib must be between 0 and %d, got %d

Error message

max_recv_msg_size_mib must be between 0 and %d, got %d

What it means

The gRPC storage factory validates MaxRecvMsgSizeMiB at startup: it must be within [0, MaxInt/1MiB]. Values outside this range would overflow the int-typed byte computation passed to grpc.WithDefaultCallOptions, so the factory refuses to initialize.

Source

Thrown at internal/storage/v2/grpc/factory.go:126

		Logger:         telset.Logger,
		TracerProvider: tracerProvider,
		MeterProvider:  telset.MeterProvider,
	}
}

type newClientFn func(telset component.TelemetrySettings, gcs *configgrpc.ClientConfig, opts ...grpc.DialOption) (*grpc.ClientConn, error)

func (f *Factory) initializeConnections(
	readerTelset, writerTelset component.TelemetrySettings,
	readerConfig, writerConfig *configgrpc.ClientConfig,
	newClient newClientFn,
) error {
	if f.config.Auth.HasValue() {
		return errors.New("authenticator is not supported")
	}
	const maxRecvMsgSizeMiB = math.MaxInt / (1024 * 1024)
	if f.config.MaxRecvMsgSizeMiB < 0 || f.config.MaxRecvMsgSizeMiB > maxRecvMsgSizeMiB {
		return fmt.Errorf("max_recv_msg_size_mib must be between 0 and %d, got %d", maxRecvMsgSizeMiB, f.config.MaxRecvMsgSizeMiB)
	}

	unaryInterceptors := []grpc.UnaryClientInterceptor{bearertoken.NewUnaryClientInterceptor()}
	streamInterceptors := []grpc.StreamClientInterceptor{bearertoken.NewStreamClientInterceptor()}

	if tenancyMgr := tenancy.NewManager(&f.config.Tenancy); tenancyMgr.Enabled {
		unaryInterceptors = append(unaryInterceptors, tenancy.NewClientUnaryInterceptor(tenancyMgr))
		streamInterceptors = append(streamInterceptors, tenancy.NewClientStreamInterceptor(tenancyMgr))
	}

	// HeaderForwarding acts as an enable switch: header capture happens on the query
	// server side (HTTP/gRPC server interceptors); the client interceptors here simply
	// forward whatever was captured into outgoing metadata.
	if len(f.config.HeaderForwarding) > 0 {
		unaryInterceptors = append(unaryInterceptors, headerforwarding.NewUnaryClientInterceptor())
		streamInterceptors = append(streamInterceptors, headerforwarding.NewStreamClientInterceptor())
	}

View on GitHub (pinned to 806f444784)

Solutions

  1. Set max_recv_msg_size_mib to a sane positive value (e.g. 4-64 MiB)
  2. Confirm the config unit is MiB, not bytes — do not enter byte-sized numbers
  3. Fix config generation/template code producing negative or huge values

Example fix

// before (config)
max_recv_msg_size_mib: -1
// after
max_recv_msg_size_mib: 16
Defensive patterns

Strategy: validation

Validate before calling

const maxRecvMsgSizeMiB = math.MaxInt / (1024 * 1024)
if cfg.MaxRecvMsgSizeMiB < 0 || cfg.MaxRecvMsgSizeMiB > maxRecvMsgSizeMiB {
    return fmt.Errorf("max_recv_msg_size_mib out of range: %d", cfg.MaxRecvMsgSizeMiB)
}

Prevention

When it happens

Trigger: Setting max_recv_msg_size_mib to a negative number or a value exceeding math.MaxInt/(1024*1024) (2147483647 on 64-bit) in the gRPC storage config, during NewFactory -> initializeConnections.

Common situations: Typo in YAML (e.g. -1); attempting to set an absurdly large receive limit without unit awareness; config generated programmatically with unbounded values.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of jaegertracing/jaeger@806f444784 (2026-09-01). Data as JSON: /api/errors/bc94b18195e8e542. Report an issue: GitHub.