googleapis/mcp-toolbox · error
failed to read object %q in bucket %q: %w
Error message
failed to read object %q in bucket %q: %w
What it means
io.ReadAll failed while streaming the object body after it was opened successfully. The wrapped error is usually a network interruption mid-read, a context cancellation/deadline, or an integrity/checksum mismatch reported by the GCS client.
Source
Thrown at internal/sources/cloudstorage/cloudstorage.go:266
func (s *Source) ReadObject(ctx context.Context, bucket, object string, offset, length int64) (map[string]any, error) {
if err := s.validateBucket(bucket); err != nil {
return nil, err
}
reader, err := s.client.Bucket(bucket).Object(object).NewRangeReader(ctx, offset, length)
if err != nil {
return nil, fmt.Errorf("failed to open object %q in bucket %q: %w", object, bucket, err)
}
defer reader.Close()
if remain := reader.Remain(); remain > defaultMaxReadBytes {
return nil, fmt.Errorf("object %q: %d bytes exceeds %d byte limit: %w",
object, remain, defaultMaxReadBytes,
cloudstoragecommon.ErrReadSizeLimitExceeded)
}
data, err := io.ReadAll(reader)
if err != nil {
return nil, fmt.Errorf("failed to read object %q in bucket %q: %w", object, bucket, err)
}
if !utf8.Valid(data) {
return nil, fmt.Errorf("object %q in bucket %q: %w", object, bucket,
cloudstoragecommon.ErrBinaryContent)
}
return map[string]any{
"content": string(data),
"contentType": reader.Attrs.ContentType,
"size": len(data),
}, nil
}
// ListBuckets lists buckets in a project. When project is empty, the source's
// configured project is used. maxResults == 0 returns up to the GCS per-page
// default (1000). A non-empty pageToken resumes listing. The returned map
// contains "buckets" ([]*storage.BucketAttrs) and "nextPageToken" (empty whenView on GitHub (pinned to 8cc6e09de2)
Solutions
- Retry the read with exponential backoff; transient network drops are usually recoverable.
- Extend the context timeout / remove premature cancellation so the full read can complete.
- Reduce the amount read per call (smaller offset/length ranges) to shorten each transfer.
- If errors persist with checksum/integrity messages, verify the object isn't being mutated mid-read and check proxy/LB idle timeouts.
Example fix
// before ctx := context.Background() res, err := source.ReadObject(ctx, "bkt", "obj", 0, -1) // cancelled mid-read // after ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) defer cancel() res, err := source.ReadObject(ctx, "bkt", "obj", 0, -1) // retry once on transient err
Defensive patterns
Strategy: retry
Validate before calling
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) defer cancel()
Try / catch
if errors.Is(ctx.Err(), context.DeadlineExceeded) || errors.Is(ctx.Err(), context.Canceled) {
// extend timeout / reschedule
}
// otherwise retry the read with exponential backoff Prevention
- Set generous context timeouts for object reads.
- Read in smaller ranges so a single transfer completes quickly.
- Avoid mutating objects while reading them.
- Check proxy/LB idle-timeout settings for long transfers.
When it happens
Trigger: ReadObject on an object where the connection drops mid-transfer, the context is cancelled (client timeout, server shutdown), or the GCS client detects a corrupted response (CRC mismatch).
Common situations: Long reads over flaky networks or mobile/VPN links; server-side request timeouts shorter than download duration on huge objects; context deadlines from the MCP client expiring during transfer.
Related errors
- failed to open object %q in bucket %q: %w
- failed to list objects in bucket %q: %w
- object %q: %d bytes exceeds %d byte limit: %w
- failed to read Google tokeninfo response: %w
- object %q in bucket %q: %w
AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05).
Data as JSON: /api/errors/99ce2559bf372b03.
Report an issue: GitHub.