apache/beam · error

Failed to read object for

Error message

Failed to read object for %v

What it means

GetArtifact opens a GCS reader on the artifact object before streaming it in 1MB chunks. This wrapped error is returned when the GCS NewReader call fails, meaning the artifact object could not be opened for reading.

Solutions

  1. Verify the object exists: gsutil stat gs://bucket/object from the manifest's blob URI.
  2. Grant the retrieval service's account storage.objects.get on the artifact bucket.
  3. Re-upload the artifacts and regenerate the manifest so blob URIs are current.

Example fix

// before: reading from a stale manifest
server, _ := NewRetrievalServer(ctx, staleManifest)
// after: rebuild server from a fresh manifest
fresh, _ := ReadProxyManifest(ctx, manifestPath)
server, _ := NewRetrievalServer(ctx, fresh)
Defensive patterns

Strategy: fallback

Validate before calling

func blobExists(ctx context.Context, cl *storage.Client, bucket, object string) bool { _, err := cl.Bucket(bucket).Object(object).Attrs(ctx); return err == nil }

Try / catch

err := streamArtifact(ctx, key)
if err != nil && strings.Contains(err.Error(), "Failed to read object") {
    return fmt.Errorf("artifact blob %s unreadable (deleted or no access): %w", key, err)
}

Prevention

When it happens

Trigger: Calling GetArtifact where the mapped blob URI points to a nonexistent, deleted, or permission-restricted object, so GCS returns 404/403 on reader creation.

Common situations: Artifact blobs garbage-collected after the manifest was created, bucket permissions changed, or blob URIs pointing to the wrong bucket after re-staging.

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


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/e6e1e784be10111f. Report an issue: GitHub.

Appendix: source

Thrown at sdks/go/pkg/beam/artifact/gcsproxy/retrieval.go:100

func (s *RetrievalServer) GetArtifact(req *jobpb.LegacyGetArtifactRequest, stream jobpb.LegacyArtifactRetrievalService_GetArtifactServer) error {
	key := req.GetName()
	blob, ok := s.blobs[key]
	if !ok {
		return errors.Errorf("artifact %v not found", key)
	}

	bucket, object := parseObject(blob)

	ctx := stream.Context()
	client, err := gcsx.NewClient(ctx, storage.ScopeReadOnly)
	if err != nil {
		return errors.Wrapf(err, "Failed to create client for %v", key)
	}

	// Stream artifact in up to 1MB chunks.
	r, err := client.Bucket(bucket).Object(object).NewReader(ctx)
	if err != nil {
		return errors.Wrapf(err, "Failed to read object for %v", key)
	}
	defer r.Close()

	data := make([]byte, 1<<20)
	for {
		n, err := r.Read(data)
		if n > 0 {
			if err := stream.Send(&jobpb.ArtifactChunk{Data: data[:n]}); err != nil {
				return errors.Wrap(err, "chunk send failed")
			}
		}
		if err == io.EOF {
			break
		}
		if err != nil {
			return errors.Wrapf(err, "failed to read from %v", blob)
		}
	}

View on GitHub (pinned to 12126d8942)