thanos-io/thanos · error
get object attributes of
Error message
get object attributes of %s
What it means
newChunkedIndexReader starts WriteBinary by fetching object-storage attributes (size) of the block's index file at <block-id>/index. This error wraps a failure of bkt.Attributes(ctx, indexFilepath): the object could not be stat'ed in the bucket (does not exist, no permission, or the object-store request failed).
Solutions
- Verify the object <block-id>/index exists in the bucket (aws s3 ls / gsutil ls on the exact path).
- Check the Thanos objstore config (bucket name, endpoint, prefix) for typos.
- Verify the credentials/IAM role allow Head/Get on the bucket objects.
- If the block was deleted by compaction/retention, remove it from the store-gateway's bucket index / meta.json state and re-sync.
- Check network connectivity and object-store service status; retry on transient 5xx.
Example fix
// before: assume attributes always available
attrs, err := bkt.Attributes(ctx, indexFilepath)
// after: caller-side preflight
var exists bool
err := bkt.Iter(ctx, id.String()+"/", func(string) error { exists = true; return nil })
if err != nil || !exists {
return nil, errors.New("block missing from bucket; re-sync or restore")
} Defensive patterns
Strategy: validation
Validate before calling
// Go: verify block object presence before WriteBinary
func blockIndexExists(ctx context.Context, bkt objstore.BucketReader, id ulid.ULID) error {
exists, err := bkt.Exists(ctx, path.Join(id.String(), block.IndexFilename))
if err != nil { return err }
if !exists { return errors.Errorf("block %s index object missing from bucket", id) }
return nil
} Try / catch
// Go
_, err := indexheader.WriteBinary(ctx, bkt, id, dst)
if err != nil && strings.Contains(err.Error(), "get object attributes of") {
var nf objstoreNotFoundError // or check errors.Is on provider SDK error
if errors.As(err, &nf) {
log.Warn("block index vanished from bucket; dropping local reference", "block", id)
return ErrBlockMissing // handle upstream instead of crash-looping
}
return err
} Prevention
- Validate the objstore config with `thanos tools bucket verify` before rollout.
- Grant IAM HeadObject/GetObject (s3:GetObject, storage.objects.get) to the service account.
- Enable the Thanos bucket index / metadata cache to detect deleted blocks consistently.
- Alert on store-gateway crash-loops with attribute errors — usually missing or GC'ed blocks.
When it happens
Trigger: WriteBinary -> newChunkedIndexReader -> bkt.Attributes(ctx, "<ulid>/index") failing: the block's index object is missing from the bucket (block deleted/partially uploaded), the bucket credentials lack s3:GetObject/HeadObject, the bucket name is wrong, or the object store is unreachable (DNS, 403, 5xx).
Common situations: Store Gateway pointed at a bucket where the block was garbage-collected; misconfigured bucket/prefix in the Thanos objstore config; IAM policies stripped HeadObject permission; network outage or wrong endpoint in the objstore provider config.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- index header PostingsOffset
- read postings range
- compaction
- sync before first pass of downsampling
- sync before second pass of downsampling
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/3dbf60a0ce52ab74.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/block/indexheader/binary_reader.go:185
return nil, os.Rename(tmpFilename, filename)
}
return bw.Buffer(), nil
}
type chunkedIndexReader struct {
ctx context.Context
path string
size uint64
bkt objstore.BucketReader
toc *index.TOC
}
func newChunkedIndexReader(ctx context.Context, bkt objstore.BucketReader, id ulid.ULID) (*chunkedIndexReader, int, error) {
indexFilepath := filepath.Join(id.String(), block.IndexFilename)
attrs, err := bkt.Attributes(ctx, indexFilepath)
if err != nil {
return nil, 0, errors.Wrapf(err, "get object attributes of %s", indexFilepath)
}
rc, err := bkt.GetRange(ctx, indexFilepath, 0, index.HeaderLen)
if err != nil {
return nil, 0, errors.Wrapf(err, "get TOC from object storage of %s", indexFilepath)
}
b, err := io.ReadAll(rc)
if err != nil {
runutil.CloseWithErrCapture(&err, rc, "close reader")
return nil, 0, errors.Wrapf(err, "get header from object storage of %s", indexFilepath)
}
if err := rc.Close(); err != nil {
return nil, 0, errors.Wrap(err, "close reader")
}
if m := binary.BigEndian.Uint32(b[0:4]); m != index.MagicIndex {View on GitHub (pinned to 35b8b99117)