Skip to content

Fix GCS not-found detection to unwrap ErrObjectNotExist (#358)#359

Merged
folbricht merged 1 commit into
masterfrom
fix-gcs-object-not-exist
Jun 18, 2026
Merged

Fix GCS not-found detection to unwrap ErrObjectNotExist (#358)#359
folbricht merged 1 commit into
masterfrom
fix-gcs-object-not-exist

Conversation

@folbricht

Copy link
Copy Markdown
Owner

Problem

desync make fails when it encounters a chunk that doesn't yet exist in a Google Cloud Storage bucket, aborting with:

Error: storage: object doesn't exist: googleapi: Error 404: No such object

The missing object is expected — it's a new chunk awaiting upload — and should be treated as a cache miss, not a fatal error.

Root cause

gcs.go detected "object not found" using direct equality (err == storage.ErrObjectNotExist) in three places (GetChunk after NewReader and after io.ReadAll, and HasChunk after Attrs).

The dependency bump in a452c77 (cloud.google.com/go/storage v1.30.1 → v1.60.0) changed the library to wrap the sentinel rather than return it bare. formatObjectErr now does:

return fmt.Errorf("%w: %w", ErrObjectNotExist, err)

so the returned error is no longer == storage.ErrObjectNotExist. Both Attrs and NewReader route through formatObjectErr, producing exactly the "storage: object doesn't exist: googleapi: Error 404: No such object" message above.

In ChunkStorage.StoreChunk, the dedup check if hasChunk, err := s.ws.HasChunk(...); err != nil || hasChunk then propagates this misclassified error and aborts the whole make. The same flaw also turns legitimate read misses in GetChunk into hard errors instead of ChunkMissing, breaking cache/failover self-repair. (S3 is unaffected; it uses status-code-based detection.)

Fix

Use errors.Is, which unwraps the chain, in all three locations. No import change is needed — github.com/pkg/errors (already imported) passes Is straight through to the stdlib.

Fixes #358

cloud.google.com/go/storage v1.60.0 (bumped from v1.30.1 in a452c77)
now wraps storage.ErrObjectNotExist via formatObjectErr instead of
returning the bare sentinel. The direct equality checks
(err == storage.ErrObjectNotExist) in GetChunk and HasChunk therefore
no longer match, so expected cache misses are misclassified as fatal
errors. This made "desync make" abort with "storage: object doesn't
exist: googleapi: Error 404: No such object" when storing a new chunk.

Use errors.Is, which unwraps, in all three locations.
@folbricht folbricht merged commit f67d01e into master Jun 18, 2026
3 checks passed
@folbricht folbricht deleted the fix-gcs-object-not-exist branch June 18, 2026 06:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

GCS store: desync make fails with "object doesn't exist" on chunks that should be uploaded

1 participant