SigNoz/signoz · warning · errors.SignozError

CodeInternal

CodeInternal

Error message

error writing to cache

What it means

Returned by the in-memory (ristretto) cache Set when SetWithTTL returns false, meaning ristretto declined to admit the entry (its admission policy rejected it, or the cache was closed). The library surfaces this as an internal error rather than silently dropping the entry.

Source

Thrown at pkg/cache/memorycache/provider.go:124

	if err != nil {
		return err
	}

	// To make sure ristretto does not go into no-op
	if ttl < 0 {
		provider.settings.Logger().WarnContext(ctx, "ttl is less than 0, setting it to 0")
		ttl = 0
	}

	if cloneable, ok := data.(cachetypes.Cloneable); ok {
		cost := max(cloneable.Cost(), 1)
		// Clamp to a minimum of 1: ristretto treats cost 0 specially and we
		// never want zero-size entries to bypass admission accounting.
		span.SetAttributes(attribute.Bool("memory.cloneable", true))
		span.SetAttributes(attribute.Int64("memory.cost", cost))
		toCache := cloneable.Clone()
		if ok := provider.cc.SetWithTTL(strings.Join([]string{orgID.StringValue(), cacheKey}, "::"), toCache, cost, ttl); !ok {
			return errors.New(errors.TypeInternal, errors.CodeInternal, "error writing to cache")
		}

		provider.cc.Wait()
		return nil
	}

	toCache, err := provider.marshalBinary(ctx, data)
	if err != nil {
		return err
	}
	cost := max(int64(len(toCache)), 1)

	span.SetAttributes(attribute.Bool("memory.cloneable", false))
	span.SetAttributes(attribute.Int64("memory.cost", cost))

	if ok := provider.cc.SetWithTTL(strings.Join([]string{orgID.StringValue(), cacheKey}, "::"), toCache, cost, ttl); !ok {
		return errors.New(errors.TypeInternal, errors.CodeInternal, "error writing to cache")
	}

View on GitHub (pinned to 5069bf80b0)

Solutions

  1. Increase the memory cache capacity/numCounters tuning so ristretto admits your entries
  2. Cache smaller objects, or check entry sizes vs configured max cost
  3. Avoid Set calls after Close; guard lifecycle in shutdown paths
  4. If dropping entries is acceptable, treat this error as non-fatal and log-and-continue

Example fix

// after: tolerate admission rejection (log instead of fail)
if err := cache.Set(ctx, orgID, key, val, ttl); err != nil {
    if err.Error() == "error writing to cache" {
        log.Warn("cache admission rejected", "key", key)
    } else { return err }
}
Defensive patterns

Strategy: fallback

Type guard

func isCacheAdmissionErr(err error) bool {
    return err != nil && strings.Contains(err.Error(), "error writing to cache")
}

Try / catch

if err := cache.Set(ctx, orgID, key, v, ttl); err != nil {
    if isCacheAdmissionErr(err) {
        log.Warn("cache admission rejected; continuing without caching", "key", key)
    } else {
        return err
    }
}

Prevention

When it happens

Trigger: Calling Set on a Cloneable cacheable value whose entry ristretto rejects — cost exceeds capacity, the item is frequently rejected by the admission policy, or the cache was shut down mid-write.

Common situations: Cache capacity configured too small for large span/trace objects; many concurrent sets with tiny TTLs; calling Set after cache Close in tests or during shutdown; KeepUntil/eviction pressure.

Related errors


AI-assisted analysis of SigNoz/signoz@5069bf80b0 (2026-08-28). Data as JSON: /api/errors/f9052f514df47827. Report an issue: GitHub.