Skip to content

fix: return delete-marker ObjectInfo from StatObject alongside the error - #2273

Open
allanrogerr wants to merge 3 commits into
minio:masterfrom
allanrogerr:issue-2260-statobject-delete-marker-info
Open

fix: return delete-marker ObjectInfo from StatObject alongside the error#2273
allanrogerr wants to merge 3 commits into
minio:masterfrom
allanrogerr:issue-2260-statobject-delete-marker-info

Conversation

@allanrogerr

@allanrogerr allanrogerr commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Description

Since #2115 (first released in v7.0.93), executeMethod returns a non-nil error for every response outside its success set — 200/204/206 then, 202 added later by #2252 — so StatObject early-returns a zero ObjectInfo before its delete-marker handling block can run — leaving the block unreachable for its intended 405/404 delete-marker paths. This PR moves that logic into the err != nil branch, restoring the pre-v7.0.93 behavior:

  • Stat of a delete marker (HEAD with VersionID, answered 405 + x-amz-delete-marker: true) again returns ObjectInfo{VersionID, IsDeleteMarker} alongside a MethodNotAllowed ErrorResponse (synthesized exactly as before v7.0.93; the parsed server fields are not merged in, and ReplicationReady is likewise not merged into this return — pinned by the tests).
  • Any other error-bearing response returns the header-populated ObjectInfo (VersionID, IsDeleteMarker, ReplicationReady) alongside the error executeMethod already parsed.
  • When no response exists (resp == nil), StatObject still returns a zero ObjectInfo with the error. The old block is removed.
  • One narrow behavior change beyond the restore: 202/204 HEAD responses, which the old block turned into errors, are now parsed like a 200 (executeMethod treats them as success). No known S3 server returns these for HEAD.
  • Rides along: pins the go-rdma.yml vcpkg checkout to an immutable commit (cd61e1e2, tag 2026.06.24). vcpkg master now requires CMake >= 4.3, which vcpkg's tool bootstrap downloads on linux-amd64 but not on linux-arm64 (falling back to apt's CMake 3.28), failing every arm64 run since 2026-07-30 — unrelated to this fix, but it blocks CI here.

Fixes #2260

Is this a breaking change?

No — this is a regression-fix branch, not a breaking-change branch:

  • No API-surface change. StatObject's signature, ObjectInfo's fields, and all exported identifiers are untouched; every existing caller compiles unchanged.
  • Error contract preserved. The error path still returns a non-nil error of the same type — executeMethod builds it via httpRespToErrorResponse, so minio.ToErrorResponse(err) keeps working exactly as before.
  • The behavior change restores the documented contract. Populating VersionID/IsDeleteMarker/ReplicationReady alongside the error is what StatObject did before v7.0.93 and what StatObject no longer returns delete-marker ObjectInfo (VersionID/IsDeleteMarker) alongside the error — regression since v7.0.93 (#2115) #2260 reports as broken; v7.0.93 (Add support of error responses in 200 OK body #2115) was the unintentional behavior change, and this PR undoes it. A caller is only affected if it relied on ObjectInfo being zero-valued whenever err != nil — an anti-pattern the docs never promised (the new doc comment now spells the contract out).
  • The 202/204 change is real but practically inert. Those statuses now parse like a 200 instead of being converted to errors, but no known S3 server returns them for HEAD, and treating a success status as success is the more correct behavior.
  • The ride-along commits are CI hygiene and tests (go-rdma.yml checkout pin, new unit tests) — no public-API impact.

Motivation and Context

Callers that detect delete markers from StatObject errors (behavior added in #1379/#1397) silently lost VersionID, IsDeleteMarker, and ReplicationReady, and — for empty-body 405 responses — the MethodNotAllowed error code.

How to test this PR?

  • go test -race -run TestStatObject . — five new regression tests in api-stat_test.go:
    • TestStatObjectDeleteMarker: 405 + delete-marker headers → populated ObjectInfo, MethodNotAllowed code and 405 status. Fails on master, passes here.
    • TestStatObjectMethodNotAllowedGeneric: 405 missing either half of the delete-marker shape (no marker header, or no version-targeted stat) → the generic path with the raw status code. Fails on master, passes here.
    • TestStatObjectNoContentSuccess: 202/204 → parsed like a 200 (nil error, header-derived fields). Fails on master, passes here.
    • TestStatObjectErrorHeaders: 404 with delete-marker/replication headers → all three fields survive alongside NoSuchKey. Fails on master, passes here.
    • TestStatObjectNoResponse: unreachable endpoint → zero ObjectInfo with the error.
  • Full go test -short -race ./... passes (16 packages) on this branch (base 802bd60).
  • Live-validated (2026-07-17, against the same fix logic) on MinIO community master and AIStor master (versioned bucket → delete object → stat the marker version and the latest version): the unfixed client loses the fields on both servers; the fixed client returns MethodNotAllowed/NoSuchKey with populated info. The repro test also passes on v7.0.92, bracketing the regression to Add support of error responses in 200 OK body #2115. Note: servers that send an XML error body (such as MinIO) supply the MethodNotAllowed code from the body, so the error-code half of the regression manifests only with empty-body 405s — pinned by the unit tests.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Optimization (provides speedup with no functional changes)
  • Cleanup/Maintenance (no functional changes)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist:

Summary by CodeRabbit

  • Bug Fixes
    • Improved object metadata reporting when status requests encounter errors.
    • Preserved version and delete-marker details for relevant responses.
    • Added safer handling for missing responses and common HTTP error cases.
  • Tests
    • Added regression coverage for delete markers, successful responses, failures, and error metadata.
  • Chores
    • Improved RDMA build workflow consistency and checkout security.

@allanrogerr allanrogerr self-assigned this Aug 1, 2026
@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

StatObject now preserves response metadata on execution errors and handles missing responses safely. Regression tests cover these cases. The RDMA workflow disables credential persistence and pins vcpkg to a compatible commit.

Changes

StatObject error handling

Layer / File(s) Summary
Preserve StatObject error metadata
api-stat.go
StatObject returns version, delete-marker, and replication-readiness metadata from error responses. It returns an empty ObjectInfo when no response exists.
Validate response behavior
api-stat_test.go
Tests cover delete-marker 405 responses, generic failures, successful 202 and 204 responses, pre-response failures, and 404 headers.

RDMA workflow dependency pinning

Layer / File(s) Summary
Pin the RDMA workflow dependency
.github/workflows/go-rdma.yml
The workflow disables credential persistence, pins vcpkg to a fixed commit, and documents the arm64 CMake compatibility constraint.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant StatObject
  participant HTTPServer
  Client->>StatObject: request object status
  StatObject->>HTTPServer: execute object request
  HTTPServer-->>StatObject: response or request error
  StatObject-->>Client: ObjectInfo and error metadata
Loading

Possibly related issues

  • minio/minio-go#2260 — The change addresses the StatObject delete-marker metadata regression described by this issue.

Possibly related PRs

Suggested reviewers: harshavardhana

Poem

A rabbit checks each marker bright,
Keeps version data through the night.
Empty replies stay safely clear,
Pinned tools make workflows steer.
Tests hop neatly into place.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main StatObject fix: returning delete-marker ObjectInfo alongside the error.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@api-stat.go`:
- Around line 94-120: Extend the StatObject regression tests to cover HEAD
responses with HTTP 202 and 204 status codes, asserting they return successfully
without an error. Add the remaining regression cases required by the PR
objectives, including validation of the existing delete-marker metadata
behavior, while keeping assertions focused on the public StatObject result.
- Around line 95-119: Extract the response/error handling block from StatObject
into a focused helper that accepts the response, error, request options, bucket
name, and object name, then returns ObjectInfo and error. Preserve the existing
nil-response behavior, versioned delete-marker 405 ErrorResponse construction,
and metadata population for all other responses; have StatObject delegate to
this helper so the delete-marker logic is independently testable.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 28d1b5a4-2829-4cb2-9a6f-c3acbde035da

📥 Commits

Reviewing files that changed from the base of the PR and between 802bd60 and 30f3a86.

📒 Files selected for processing (2)
  • api-stat.go
  • api-stat_test.go

Comment thread api-stat.go
Comment thread api-stat.go Outdated
StatObject's delete-marker block became unreachable for its intended
405/404 paths after minio#2115 made executeMethod error on every response
outside its success set. Move the block into the error branch so
VersionID and IsDeleteMarker plus the MethodNotAllowed code (405 path)
and ReplicationReady (other error responses) reach callers again, as
before v7.0.93.

Fixes minio#2260
@allanrogerr
allanrogerr force-pushed the issue-2260-statobject-delete-marker-info branch from 30f3a86 to 2bd0f11 Compare August 1, 2026 12:05
The go-rdma workflow checks out microsoft/vcpkg master at run time.
Since vcpkg commit 5397c5c9f its port scripts use
string(JSON ... STRING_ENCODE), which needs a newer CMake than the
ubuntu-24.04-arm runner provides, so every arm64 run fails while
building openssl before Go is even set up. Pin vcpkg to the commit
behind release 2026.06.24, the last release that predates the change;
the amd64 lane is unaffected because vcpkg bootstraps its own newer
CMake there. The tag anchor comment records the human-readable
version for future bumps. No third-party container images exist in
this repo's workflows to digest-pin alongside it.
@allanrogerr
allanrogerr marked this pull request as ready for review August 1, 2026 13:16

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@api-stat_test.go`:
- Around line 33-236: Extract the repeated httptest server setup and client
construction from TestStatObjectDeleteMarker,
TestStatObjectMethodNotAllowedGeneric, TestStatObjectNoContentSuccess,
TestStatObjectNoResponse, and TestStatObjectErrorHeaders into a shared
newTestStatClient helper. Have the helper accept the request handler, register
server cleanup, construct the configured Client, and fail the test on setup
errors; update each test to use it while preserving its existing handler and
assertions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 1317c55f-3682-4bbc-b1c6-71e79e6e3b6a

📥 Commits

Reviewing files that changed from the base of the PR and between 30f3a86 and 46683fe.

📒 Files selected for processing (3)
  • .github/workflows/go-rdma.yml
  • api-stat.go
  • api-stat_test.go

Comment thread api-stat_test.go Outdated
…hygiene

Correct the StatObject error-branch comment and godoc to state only what
each path surfaces, restore the ReplicationReady field note, extract a
newTestStatClient helper with strengthened delete-marker assertions, fix
the vcpkg pin comment (CMake >= 4.3 arrives via vcpkg's per-arch tool
bootstrap, absent on arm64), and set persist-credentials: false on all
three go-rdma.yml checkouts.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/go-rdma.yml:
- Line 31: Update every actions/checkout step in the go-rdma workflow, including
the minio-go, minio-cpp, and vcpkg checkout steps, to reference the intended
actions/checkout v4 release by its full immutable commit SHA instead of the
mutable `@v4` tag.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: b853a8f7-d94c-49f8-ab93-b25c80cd27b9

📥 Commits

Reviewing files that changed from the base of the PR and between 46683fe and d3d5611.

📒 Files selected for processing (3)
  • .github/workflows/go-rdma.yml
  • api-stat.go
  • api-stat_test.go

Comment thread .github/workflows/go-rdma.yml
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.

StatObject no longer returns delete-marker ObjectInfo (VersionID/IsDeleteMarker) alongside the error — regression since v7.0.93 (#2115)

1 participant