cilium/cilium · error

missing snapshot

Error message

missing snapshot

What it means

ConstructVersionMap on a ciliumSnapshot returns the sentinel error 'missing snapshot' when the receiver w is nil. The version map is needed by the go-control-plane cache to compute resource versions; a nil snapshot has none. Callers use this as an explicit guard rather than panicking on a nil dereference.

Source

Thrown at pkg/envoy/xdsnew/cache.go:131

	}
	out := make(map[string]cache_types.Resource, len(resources))
	for name, resource := range resources {
		out[name] = resource.Resource
	}
	return out
}

func (w *ciliumSnapshot) GetResourcesAndTTL(typeURL string) map[string]cache_types.ResourceWithTTL {
	group, ok := w.Resources[typeURL]
	if !ok {
		return nil
	}
	return group.Items
}

func (w *ciliumSnapshot) ConstructVersionMap() error {
	if w == nil {
		return fmt.Errorf("missing snapshot")
	}
	if w.VersionMap != nil {
		return nil
	}

	w.VersionMap = make(map[string]map[string]string, len(w.Resources))
	for typeURL, group := range w.Resources {
		if len(group.Items) == 0 {
			continue
		}
		w.VersionMap[typeURL] = make(map[string]string, len(group.Items))
		for name, resource := range group.Items {
			marshaledResource, err := cache.MarshalResource(resource.Resource)
			if err != nil {
				return err
			}
			w.VersionMap[typeURL][name] = cache.HashResource(marshaledResource)
		}

View on GitHub (pinned to ac7b90affa)

Solutions

  1. Verify the node ID used to fetch the snapshot exists in the snapshot cache (SetSnapshot was called for it).
  2. Check for races where RemoveSnapshot/eviction runs while the snapshot is still being used; serialize cache lifecycle operations.
  3. Add a nil check before calling ConstructVersionMap in custom code built around ciliumSnapshot.
  4. If this occurs inside stock Cilium flows, capture logs and file an issue — a nil snapshot reaching ConstructVersionMap indicates a cache lifecycle bug.

Example fix

// before
err := snapshot.ConstructVersionMap()
// after
if snapshot == nil {
    return fmt.Errorf("no snapshot available for node")
}
err := snapshot.ConstructVersionMap()
Defensive patterns

Strategy: type-guard

Type guard

func snapshotReady(s cache.ResourceSnapshot) bool {
    cs, ok := s.(*ciliumSnapshot)
    return ok && cs != nil
}

Try / catch

if err := w.ConstructVersionMap(); err != nil {
    if err.Error() == "missing snapshot" {
        // node has no snapshot; skip response or SetSnapshot first
        return cache.ErrNoSnapshot
    }
    return err
}

Prevention

When it happens

Trigger: Calling ConstructVersionMap on a nil *ciliumSnapshot — e.g. a snapshot lookup in the cache returned nil (unknown node, removed cache entry) and the code still invoked ConstructVersionMap on it.

Common situations: xDS clients requesting resources for node IDs that were never set or already evicted from the snapshot cache; races where a snapshot is deleted between fetch and use; tests constructing cache responses for nonexistent proxies.

Related errors


AI-assisted analysis of cilium/cilium@ac7b90affa (2026-08-31). Data as JSON: /api/errors/6fa6cdd5f0a078bf. Report an issue: GitHub.