weaviate/weaviate · error

LAZY_LOAD_SHARD_SIZE_THRESHOLD_GB must be >= 0

Error message

LAZY_LOAD_SHARD_SIZE_THRESHOLD_GB must be >= 0

What it means

After parsing LAZY_LOAD_SHARD_SIZE_THRESHOLD_GB as a float, FromEnv validates it is not negative and returns the literal error "LAZY_LOAD_SHARD_SIZE_THRESHOLD_GB must be >= 0" otherwise, aborting startup. A negative size threshold is meaningless for the lazy-load size auto-detection logic.

Source

Thrown at usecases/config/environment.go:210

			left = "no shard is warmed up"
		}
		logrus.Warnf("LAZY_LOAD_SHARD_WARMUP_MIN_OBJECTS is %d, so on a collection using lazy loading %s. "+
			"A HOT tenant left out stays unloaded until first access. "+
			"While it is unloaded the TTL sweep keeps its expired objects, async replication leaves a "+
			"stale replica unrepaired, and MAXIMUM_ALLOWED_OBJECTS_COUNT stops counting it, so this "+
			"node admits writes past its cap.",
			minObjects, left)
	}

	// Lazy load shard size threshold for auto-detection (in GB)
	// Determines at what total shard size auto-detection enables lazy loading
	if v := os.Getenv("LAZY_LOAD_SHARD_SIZE_THRESHOLD_GB"); v != "" {
		asFloat, err := strconv.ParseFloat(v, 64)
		if err != nil {
			return fmt.Errorf("parse LAZY_LOAD_SHARD_SIZE_THRESHOLD_GB as float: %w", err)
		}
		if asFloat < 0 {
			return fmt.Errorf("LAZY_LOAD_SHARD_SIZE_THRESHOLD_GB must be >= 0")
		}
		config.LazyLoadShardSizeThresholdGB = asFloat
	} else {
		config.LazyLoadShardSizeThresholdGB = DefaultLazyLoadShardSizeThresholdGB
	}

	if entcfg.Enabled(os.Getenv("FORCE_FULL_REPLICAS_SEARCH")) {
		config.ForceFullReplicasSearch = true
	}

	if v := os.Getenv("TRANSFER_INACTIVITY_TIMEOUT"); v != "" {
		timeout, err := time.ParseDuration(v)
		if err != nil {
			return fmt.Errorf("parse TRANSFER_INACTIVITY_TIMEOUT as duration: %w", err)
		}
		config.TransferInactivityTimeout = timeout
	} else {
		config.TransferInactivityTimeout = DefaultTransferInactivityTimeout

View on GitHub (pinned to 75aa4b6d11)

Solutions

  1. Set a non-negative value, e.g. LAZY_LOAD_SHARD_SIZE_THRESHOLD_GB=0 (0 combined with threshold 0 semantics acts as always-lazy) or a realistic size like 20.
  2. Unset the variable to use the built-in default.
  3. Reject negative values in config linting/CI before deployment.

Example fix

// before
LAZY_LOAD_SHARD_SIZE_THRESHOLD_GB=-1
// after
LAZY_LOAD_SHARD_SIZE_THRESHOLD_GB=20
Defensive patterns

Strategy: validation

Validate before calling

v := os.Getenv("LAZY_LOAD_SHARD_SIZE_THRESHOLD_GB")
if v != "" {
    f, err := strconv.ParseFloat(v, 64)
    if err != nil {
        return fmt.Errorf("not a float: %w", err)
    }
    if f < 0 {
        return fmt.Errorf("LAZY_LOAD_SHARD_SIZE_THRESHOLD_GB must be >= 0, got %v", f)
    }
}

Type guard

func validNonNegativeFloat(v string) bool {
    f, err := strconv.ParseFloat(v, 64)
    return err == nil && f >= 0
}

Prevention

When it happens

Trigger: Set LAZY_LOAD_SHARD_SIZE_THRESHOLD_GB to a negative number such as "-1" (e.g. used as a "disable" sentinel from other tooling conventions); LoadConfig -> FromEnv returns this error at environment.go:210.

Common situations: Operators assuming -1 disables the feature (Go code does not treat it that way); misconfigured arithmetic in provisioning scripts producing negative values.

Understand the failure class

Background: "is not a valid" / "Invalid ... value" environment variable errors: how libraries validate env vars and what to do when they reject yours — this error's family across 48 libraries.

Related errors


AI-assisted analysis of weaviate/weaviate@75aa4b6d11 (2026-09-04). Data as JSON: /api/errors/67efb936159c925b. Report an issue: GitHub.