{"record":{"id":"8876c8f3dc2046d6","repo":"thanos-io/thanos","slug":"errobjnotfound","errorCode":"errObjNotFound","errorMessage":"object not found","messagePattern":"object not found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/store/cache/caching_bucket.go","lineNumber":35,"sourceCode":"\t\"github.com/pkg/errors\"\n\t\"github.com/prometheus/client_golang/prometheus\"\n\t\"github.com/prometheus/client_golang/prometheus/promauto\"\n\t\"golang.org/x/sync/errgroup\"\n\n\t\"github.com/thanos-io/objstore\"\n\n\t\"github.com/thanos-io/thanos/pkg/cache\"\n\t\"github.com/thanos-io/thanos/pkg/runutil\"\n\t\"github.com/thanos-io/thanos/pkg/store/cache/cachekey\"\n)\n\nconst (\n\toriginCache  = \"cache\"\n\toriginBucket = \"bucket\"\n)\n\nvar (\n\terrObjNotFound = errors.Errorf(\"object not found\")\n)\n\n// CachingBucket implementation that provides some caching features, based on passed configuration.\ntype CachingBucket struct {\n\tobjstore.Bucket\n\n\tcfg    *cache.CachingBucketConfig\n\tlogger log.Logger\n\n\trequestedGetRangeBytes *prometheus.CounterVec\n\tfetchedGetRangeBytes   *prometheus.CounterVec\n\trefetchedGetRangeBytes *prometheus.CounterVec\n\n\toperationConfigs  map[string][]*cache.OperationConfig\n\toperationRequests *prometheus.CounterVec\n\toperationHits     *prometheus.CounterVec\n}\n","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/store/cache/caching_bucket.go#L17-L53","documentation":"CachingBucket.Get returns errObjNotFound when the cached 'exists' marker for an object is false, meaning the cache has a recent negative answer that the object does not exist in the bucket. IsObjNotFoundErr treats this sentinel the same as the underlying bucket's own not-found errors, so callers can handle both uniformly as object-not-found.","triggerScenarios":"Calling CachingBucket.Get (or Exists) for an object that a previous Get/Exists call cached as nonexistent (existence TTL not yet expired); the wrapped error is then matched via IsObjNotFoundErr.","commonSituations":"Reading objects deleted shortly after being cached as missing (or cached as present then deleted); racing a compaction/upload pipeline; block deletion while a query still references it.","solutions":["Use cb.IsObjNotFoundErr(err) to branch on not-found and skip the object instead of treating it as a hard failure.","Invalidate the cached 'exists' entry (delete the existence cache key) if the object may have been uploaded since.","Lower the existence cache TTL (ExistsTTL / eventual-upload TTL in CachingBucketConfig) so false negatives expire sooner.","Re-check the source bucket directly if stale negative caching is suspected."],"exampleFix":"// before\nrc, err := cb.Get(ctx, name)\nif err != nil {\n    return err\n}\n// after\nrc, err := cb.Get(ctx, name)\nif cb.IsObjNotFoundErr(err) {\n    return nil // object genuinely absent (or stale negative cache)\n}\nif err != nil {\n    return errors.Wrapf(err, \"get %s\", name)\n}","handlingStrategy":"try-catch","validationCode":"// Pre-check existence explicitly and accept its answer as TTL-cached\nexists, err := cb.Exists(ctx, name)\nif err == nil && !exists {\n    return nil, nil\n}","typeGuard":"func isObjNotFound(err error, cb *cache.CachingBucket) bool {\n    return cb.IsObjNotFoundErr(err)\n}","tryCatchPattern":"rc, err := cb.Get(ctx, name)\nif err != nil {\n    if cb.IsObjNotFoundErr(err) {\n        return nil, ErrObjectGone // handle uniformly as not-found\n    }\n    return errors.Wrapf(err, \"get %s\", name)\n}","preventionTips":["Always classify not-found via IsObjNotFoundErr, never string matching","Tune existence-cache TTLs to match your object lifecycle","Invalidate existence entries after uploads/deletes","Handle not-found as a normal outcome in listing/iteration code"],"tags":["go","cache","object-store","not-found"],"backgroundTag":"resource-not-found","analyzedSha":"35b8b991177def87ed52dcf10f9b6d87f07282c8","analyzedAt":"2026-09-07T01:49:59.689Z","contentChangedAt":"2026-09-07T01:49:59.689Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}