Skip to content

ListObjectsV2 start-after fails on azureblob-sdk backend with Invalid ListBlobs marker error #938

@klaudworks

Description

@klaudworks

Problem

When using S3Proxy with the azureblob-sdk backend, ListObjectsV2 requests using the start-after parameter fail with:

BlobStorageException: Status code 400
<QueryParameterName>marker</QueryParameterName>
<QueryParameterValue>kafka/topics/.../file.avro</QueryParameterValue>
<Reason>Invalid ListBlobs marker.</Reason>

Root Cause

S3's start-after parameter accepts a blob name for lexicographic filtering, but S3Proxy passes this directly to Azure's iterableByPage(marker) method, which expects an opaque continuation token. Azure rejects the blob name as invalid.

The OPAQUE_MARKERS quirk system works correctly for continuation-token pagination (where the client returns the exact token from a previous response). However, it cannot handle start-after because start-after accepts any blob name as a starting point—not just blob names previously returned as continuation tokens. There is no way to translate an arbitrary blob name to an Azure continuation token, so the request fails.

Proposed Solution

Azure SDK 12.33.0-beta.1 introduces ListBlobsOptions.setStartFrom(String), which natively supports listing blobs starting from a specific blob name—matching S3's start-after semantics.

Changes required:

  1. Upgrade azure-storage-blob to 12.33.0-beta.1
  2. Target Azure api version 2026-02-06 (in beta, not GA yet)
  3. Remove azureblob-sdk from OPAQUE_MARKERS
  4. Update AzureBlobStore.list() to use setStartFrom() instead of iterableByPage(marker)
  5. Skip first result if it matches marker (S3 start-after is exclusive; Azure startFrom is inclusive)

Current Blockers

  1. Azure SDK: The 2026-02-06 API version required for startFrom is not yet generally available. The Azure SDK currently only supports up to 2025-11-05.

  2. Azurite: Does not yet support the startFrom parameter. Tests against Azurite fail because it ignores the parameter entirely.

Status

I have a working implementation using the new startFrom parameter, which is much more elegant than the current workaround. However, if we were to adopt it yet:

  • It requires upgrading to a beta version of the Azure SDK
  • 1 Java test and ~4 s3-tests tests would have to be disabled when sending requests against Azurite.

Next Steps

Create a pull request with the proper implementation as soon as Azurite releases support for the 2026-02-06 API version.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions