or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

bucket-access-control.mdbucket-features.mdbucket-operations.mdclient-config.mdindex.mdlist-operations.mdmultipart-upload.mdobject-operations.mdpaginators-waiters.mdpresigned-urls.mdtypes.md
tile.json

paginators-waiters.mddocs/

AWS SDK for Go v2 - S3 Paginators and Waiters

This document provides comprehensive documentation for all paginators and waiters in the AWS SDK for Go v2 S3 service package.

Table of Contents

  • Paginators
  • Waiters

Paginators

Paginators provide automatic pagination for list operations, allowing you to iterate through large result sets without manually managing continuation tokens or page markers.

Common Paginator Pattern

All paginators in the S3 package follow a consistent pattern:

  1. Create a paginator using a constructor function New<Operation>Paginator
  2. Check if more pages are available using HasMorePages()
  3. Retrieve the next page using NextPage(ctx)

ListBucketsPaginator

Paginates results from the ListBuckets operation, returning all buckets owned by the authenticated sender.

Constructor

func NewListBucketsPaginator(
    client ListBucketsAPIClient,
    params *ListBucketsInput,
    optFns ...func(*ListBucketsPaginatorOptions)
) *ListBucketsPaginator

{ .api }

Parameters:

  • client (ListBucketsAPIClient) - The S3 client implementing the ListBuckets operation
  • params (*ListBucketsInput) - Input parameters for the ListBuckets operation
    • BucketRegion (*string) - Limits response to buckets in specified AWS Region
    • ContinuationToken (*string) - Token for continuing a previous list operation
    • MaxBuckets (*int32) - Maximum number of buckets to return per page
    • Prefix (*string) - Limits response to bucket names beginning with specified prefix
  • optFns (...func(*ListBucketsPaginatorOptions)) - Optional configuration functions

Returns: *ListBucketsPaginator - A new paginator instance

Options Type

type ListBucketsPaginatorOptions struct {
    Limit              int32
    StopOnDuplicateToken bool
}

{ .api }

Fields:

  • Limit (int32) - Maximum number of buckets to return per page. When the number exceeds the count of buckets owned by the account, all buckets are returned in response.
  • StopOnDuplicateToken (bool) - If true, pagination stops when the service returns a token matching the most recent token provided

Methods

HasMorePages
func (p *ListBucketsPaginator) HasMorePages() bool

{ .api }

Returns true if more pages are available, false otherwise.

NextPage
func (p *ListBucketsPaginator) NextPage(
    ctx context.Context,
    optFns ...func(*Options)
) (*ListBucketsOutput, error)

{ .api }

Retrieves the next page of results.

Parameters:

  • ctx (context.Context) - Context for cancellation and timeout
  • optFns (...func(*Options)) - Optional per-operation configuration

Returns:

  • *ListBucketsOutput - The page of results containing:
    • Buckets ([]types.Bucket) - List of buckets
    • ContinuationToken (*string) - Token for the next page (if more pages exist)
    • Owner (*types.Owner) - Owner of the buckets
    • Prefix (*string) - Prefix filter used in request
  • error - Error if the operation fails or if no more pages are available

API Client Interface

type ListBucketsAPIClient interface {
    ListBuckets(context.Context, *ListBucketsInput, ...func(*Options)) (*ListBucketsOutput, error)
}

{ .api }

Usage Example

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/s3"
)

func main() {
    // Load AWS configuration
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        log.Fatalf("unable to load SDK config, %v", err)
    }

    // Create S3 client
    client := s3.NewFromConfig(cfg)

    // Create paginator
    paginator := s3.NewListBucketsPaginator(client, &s3.ListBucketsInput{
        MaxBuckets: aws.Int32(100),
    })

    // Iterate through pages
    var allBuckets []types.Bucket
    for paginator.HasMorePages() {
        page, err := paginator.NextPage(context.TODO())
        if err != nil {
            log.Fatalf("failed to get page, %v", err)
        }
        allBuckets = append(allBuckets, page.Buckets...)
    }

    fmt.Printf("Found %d buckets\n", len(allBuckets))
    for _, bucket := range allBuckets {
        fmt.Printf("- %s\n", *bucket.Name)
    }
}

ListDirectoryBucketsPaginator

Paginates results from the ListDirectoryBuckets operation, returning all Amazon S3 directory buckets owned by the authenticated sender.

Constructor

func NewListDirectoryBucketsPaginator(
    client ListDirectoryBucketsAPIClient,
    params *ListDirectoryBucketsInput,
    optFns ...func(*ListDirectoryBucketsPaginatorOptions)
) *ListDirectoryBucketsPaginator

{ .api }

Parameters:

  • client (ListDirectoryBucketsAPIClient) - The S3 client implementing the ListDirectoryBuckets operation
  • params (*ListDirectoryBucketsInput) - Input parameters for the ListDirectoryBuckets operation
    • ContinuationToken (*string) - Token for continuing a previous list operation
    • MaxDirectoryBuckets (*int32) - Maximum number of directory buckets to return per page
  • optFns (...func(*ListDirectoryBucketsPaginatorOptions)) - Optional configuration functions

Returns: *ListDirectoryBucketsPaginator - A new paginator instance

Options Type

type ListDirectoryBucketsPaginatorOptions struct {
    Limit              int32
    StopOnDuplicateToken bool
}

{ .api }

Fields:

  • Limit (int32) - Maximum number of directory buckets to return per page. When the number exceeds the count of buckets owned by the account, all buckets are returned.
  • StopOnDuplicateToken (bool) - If true, pagination stops when the service returns a token matching the most recent token provided

Methods

HasMorePages
func (p *ListDirectoryBucketsPaginator) HasMorePages() bool

{ .api }

Returns true if more pages are available, false otherwise.

NextPage
func (p *ListDirectoryBucketsPaginator) NextPage(
    ctx context.Context,
    optFns ...func(*Options)
) (*ListDirectoryBucketsOutput, error)

{ .api }

Retrieves the next page of results.

Parameters:

  • ctx (context.Context) - Context for cancellation and timeout
  • optFns (...func(*Options)) - Optional per-operation configuration

Returns:

  • *ListDirectoryBucketsOutput - The page of results containing:
    • Buckets ([]types.Bucket) - List of directory buckets
    • ContinuationToken (*string) - Token for the next page (if more pages exist)
  • error - Error if the operation fails or if no more pages are available

API Client Interface

type ListDirectoryBucketsAPIClient interface {
    ListDirectoryBuckets(context.Context, *ListDirectoryBucketsInput, ...func(*Options)) (*ListDirectoryBucketsOutput, error)
}

{ .api }

Usage Example

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/s3"
)

func main() {
    // Load AWS configuration
    cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithRegion("us-east-1"))
    if err != nil {
        log.Fatalf("unable to load SDK config, %v", err)
    }

    // Create S3 client
    client := s3.NewFromConfig(cfg)

    // Create paginator
    paginator := s3.NewListDirectoryBucketsPaginator(client, &s3.ListDirectoryBucketsInput{
        MaxDirectoryBuckets: aws.Int32(50),
    })

    // Iterate through pages
    pageNum := 0
    for paginator.HasMorePages() {
        pageNum++
        page, err := paginator.NextPage(context.TODO())
        if err != nil {
            log.Fatalf("failed to get page %d, %v", pageNum, err)
        }

        fmt.Printf("Page %d: %d directory buckets\n", pageNum, len(page.Buckets))
        for _, bucket := range page.Buckets {
            fmt.Printf("  - %s (created: %v)\n", *bucket.Name, *bucket.CreationDate)
        }
    }
}

ListMultipartUploadsPaginator

Paginates results from the ListMultipartUploads operation, returning in-progress multipart uploads in a bucket.

Constructor

func NewListMultipartUploadsPaginator(
    client ListMultipartUploadsAPIClient,
    params *ListMultipartUploadsInput,
    optFns ...func(*ListMultipartUploadsPaginatorOptions)
) *ListMultipartUploadsPaginator

{ .api }

Parameters:

  • client (ListMultipartUploadsAPIClient) - The S3 client implementing the ListMultipartUploads operation
  • params (*ListMultipartUploadsInput) - Input parameters for the ListMultipartUploads operation
    • Bucket (*string, required) - Bucket name
    • KeyMarker (*string) - Key marker from previous response for pagination
    • UploadIdMarker (*string) - Upload ID marker from previous response for pagination
    • MaxUploads (*int32) - Maximum number of uploads to return per page
    • Delimiter (*string) - Character used to group keys
    • EncodingType (types.EncodingType) - Encoding type for response keys
    • ExpectedBucketOwner (*string) - Account ID of expected bucket owner
    • Prefix (*string) - Limits response to keys beginning with specified prefix
    • RequestPayer (types.RequestPayer) - Confirms requester pays for request
  • optFns (...func(*ListMultipartUploadsPaginatorOptions)) - Optional configuration functions

Returns: *ListMultipartUploadsPaginator - A new paginator instance

Options Type

type ListMultipartUploadsPaginatorOptions struct {
    Limit              int32
    StopOnDuplicateToken bool
}

{ .api }

Fields:

  • Limit (int32) - Maximum number of multipart uploads to return per page
  • StopOnDuplicateToken (bool) - If true, pagination stops when the service returns a token matching the most recent token provided

Methods

HasMorePages
func (p *ListMultipartUploadsPaginator) HasMorePages() bool

{ .api }

Returns true if more pages are available, false otherwise.

NextPage
func (p *ListMultipartUploadsPaginator) NextPage(
    ctx context.Context,
    optFns ...func(*Options)
) (*ListMultipartUploadsOutput, error)

{ .api }

Retrieves the next page of results.

Parameters:

  • ctx (context.Context) - Context for cancellation and timeout
  • optFns (...func(*Options)) - Optional per-operation configuration

Returns:

  • *ListMultipartUploadsOutput - The page of results containing:
    • Uploads ([]types.MultipartUpload) - List of in-progress multipart uploads
    • IsTruncated (*bool) - Indicates if list is truncated
    • NextKeyMarker (*string) - Key marker for next page
    • NextUploadIdMarker (*string) - Upload ID marker for next page
    • CommonPrefixes ([]types.CommonPrefix) - Common prefixes if delimiter was specified
    • Bucket (*string) - Bucket name
    • Delimiter (*string) - Delimiter used
    • EncodingType (types.EncodingType) - Encoding type used
    • KeyMarker (*string) - Key marker used in request
    • MaxUploads (*int32) - Maximum uploads requested
    • Prefix (*string) - Prefix filter used
    • UploadIdMarker (*string) - Upload ID marker used in request
  • error - Error if the operation fails or if no more pages are available

API Client Interface

type ListMultipartUploadsAPIClient interface {
    ListMultipartUploads(context.Context, *ListMultipartUploadsInput, ...func(*Options)) (*ListMultipartUploadsOutput, error)
}

{ .api }

Usage Example

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/s3"
)

func main() {
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        log.Fatalf("unable to load SDK config, %v", err)
    }

    client := s3.NewFromConfig(cfg)

    // Create paginator for multipart uploads
    paginator := s3.NewListMultipartUploadsPaginator(client, &s3.ListMultipartUploadsInput{
        Bucket:     aws.String("my-bucket"),
        MaxUploads: aws.Int32(100),
        Prefix:     aws.String("uploads/"),
    })

    // Iterate through all in-progress uploads
    totalUploads := 0
    for paginator.HasMorePages() {
        page, err := paginator.NextPage(context.TODO())
        if err != nil {
            log.Fatalf("failed to get page, %v", err)
        }

        for _, upload := range page.Uploads {
            totalUploads++
            fmt.Printf("Upload ID: %s, Key: %s, Initiated: %v\n",
                *upload.UploadId, *upload.Key, *upload.Initiated)
        }
    }

    fmt.Printf("\nTotal in-progress uploads: %d\n", totalUploads)
}

ListObjectVersionsPaginator

Paginates results from the ListObjectVersions operation, returning metadata about all versions of objects in a bucket.

Constructor

func NewListObjectVersionsPaginator(
    client ListObjectVersionsAPIClient,
    params *ListObjectVersionsInput,
    optFns ...func(*ListObjectVersionsPaginatorOptions)
) *ListObjectVersionsPaginator

{ .api }

Parameters:

  • client (ListObjectVersionsAPIClient) - The S3 client implementing the ListObjectVersions operation
  • params (*ListObjectVersionsInput) - Input parameters for the ListObjectVersions operation
    • Bucket (*string, required) - Bucket name
    • KeyMarker (*string) - Key marker for pagination
    • VersionIdMarker (*string) - Version ID marker for pagination
    • MaxKeys (*int32) - Maximum number of keys to return per page
    • Delimiter (*string) - Character used to group keys
    • EncodingType (types.EncodingType) - Encoding type for response keys
    • ExpectedBucketOwner (*string) - Account ID of expected bucket owner
    • Prefix (*string) - Limits response to keys beginning with specified prefix
    • RequestPayer (types.RequestPayer) - Confirms requester pays for request
    • OptionalObjectAttributes ([]types.OptionalObjectAttributes) - Optional fields to include in response
  • optFns (...func(*ListObjectVersionsPaginatorOptions)) - Optional configuration functions

Returns: *ListObjectVersionsPaginator - A new paginator instance

Options Type

type ListObjectVersionsPaginatorOptions struct {
    Limit              int32
    StopOnDuplicateToken bool
}

{ .api }

Fields:

  • Limit (int32) - Maximum number of object versions to return per page
  • StopOnDuplicateToken (bool) - If true, pagination stops when the service returns a token matching the most recent token provided

Methods

HasMorePages
func (p *ListObjectVersionsPaginator) HasMorePages() bool

{ .api }

Returns true if more pages are available, false otherwise.

NextPage
func (p *ListObjectVersionsPaginator) NextPage(
    ctx context.Context,
    optFns ...func(*Options)
) (*ListObjectVersionsOutput, error)

{ .api }

Retrieves the next page of results.

Parameters:

  • ctx (context.Context) - Context for cancellation and timeout
  • optFns (...func(*Options)) - Optional per-operation configuration

Returns:

  • *ListObjectVersionsOutput - The page of results containing:
    • Versions ([]types.ObjectVersion) - List of object versions
    • DeleteMarkers ([]types.DeleteMarkerEntry) - List of delete markers
    • IsTruncated (*bool) - Indicates if list is truncated
    • NextKeyMarker (*string) - Key marker for next page
    • NextVersionIdMarker (*string) - Version ID marker for next page
    • CommonPrefixes ([]types.CommonPrefix) - Common prefixes if delimiter was specified
    • Delimiter (*string) - Delimiter used
    • EncodingType (types.EncodingType) - Encoding type used
    • KeyMarker (*string) - Key marker used in request
    • MaxKeys (*int32) - Maximum keys requested
    • Name (*string) - Bucket name
    • Prefix (*string) - Prefix filter used
    • VersionIdMarker (*string) - Version ID marker used in request
  • error - Error if the operation fails or if no more pages are available

API Client Interface

type ListObjectVersionsAPIClient interface {
    ListObjectVersions(context.Context, *ListObjectVersionsInput, ...func(*Options)) (*ListObjectVersionsOutput, error)
}

{ .api }

Usage Example

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/s3"
)

func main() {
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        log.Fatalf("unable to load SDK config, %v", err)
    }

    client := s3.NewFromConfig(cfg)

    // Create paginator for object versions
    paginator := s3.NewListObjectVersionsPaginator(client, &s3.ListObjectVersionsInput{
        Bucket:  aws.String("my-versioned-bucket"),
        MaxKeys: aws.Int32(1000),
        Prefix:  aws.String("documents/"),
    })

    // Iterate through all versions
    totalVersions := 0
    totalDeleteMarkers := 0

    for paginator.HasMorePages() {
        page, err := paginator.NextPage(context.TODO())
        if err != nil {
            log.Fatalf("failed to get page, %v", err)
        }

        // Process object versions
        for _, version := range page.Versions {
            totalVersions++
            fmt.Printf("Key: %s, VersionId: %s, IsLatest: %t, Size: %d\n",
                *version.Key, *version.VersionId, aws.ToBool(version.IsLatest),
                aws.ToInt64(version.Size))
        }

        // Process delete markers
        for _, marker := range page.DeleteMarkers {
            totalDeleteMarkers++
            fmt.Printf("Delete Marker: %s, VersionId: %s, IsLatest: %t\n",
                *marker.Key, *marker.VersionId, aws.ToBool(marker.IsLatest))
        }
    }

    fmt.Printf("\nTotal versions: %d\n", totalVersions)
    fmt.Printf("Total delete markers: %d\n", totalDeleteMarkers)
}

ListObjectsV2Paginator

Paginates results from the ListObjectsV2 operation, returning objects in a bucket. This is the recommended version for listing objects.

Constructor

func NewListObjectsV2Paginator(
    client ListObjectsV2APIClient,
    params *ListObjectsV2Input,
    optFns ...func(*ListObjectsV2PaginatorOptions)
) *ListObjectsV2Paginator

{ .api }

Parameters:

  • client (ListObjectsV2APIClient) - The S3 client implementing the ListObjectsV2 operation
  • params (*ListObjectsV2Input) - Input parameters for the ListObjectsV2 operation
    • Bucket (*string, required) - Bucket name
    • ContinuationToken (*string) - Token for continuing previous list operation
    • MaxKeys (*int32) - Maximum number of keys to return per page (default: 1000)
    • Delimiter (*string) - Character used to group keys
    • EncodingType (types.EncodingType) - Encoding type for response keys
    • ExpectedBucketOwner (*string) - Account ID of expected bucket owner
    • FetchOwner (*bool) - If true, includes owner information in response
    • OptionalObjectAttributes ([]types.OptionalObjectAttributes) - Optional fields to include
    • Prefix (*string) - Limits response to keys beginning with specified prefix
    • RequestPayer (types.RequestPayer) - Confirms requester pays for request
    • StartAfter (*string) - Starts listing after this specified key
  • optFns (...func(*ListObjectsV2PaginatorOptions)) - Optional configuration functions

Returns: *ListObjectsV2Paginator - A new paginator instance

Options Type

type ListObjectsV2PaginatorOptions struct {
    Limit              int32
    StopOnDuplicateToken bool
}

{ .api }

Fields:

  • Limit (int32) - Maximum number of keys to return per page. Response might contain fewer keys but will never contain more.
  • StopOnDuplicateToken (bool) - If true, pagination stops when the service returns a token matching the most recent token provided

Methods

HasMorePages
func (p *ListObjectsV2Paginator) HasMorePages() bool

{ .api }

Returns true if more pages are available, false otherwise.

NextPage
func (p *ListObjectsV2Paginator) NextPage(
    ctx context.Context,
    optFns ...func(*Options)
) (*ListObjectsV2Output, error)

{ .api }

Retrieves the next page of results.

Parameters:

  • ctx (context.Context) - Context for cancellation and timeout
  • optFns (...func(*Options)) - Optional per-operation configuration

Returns:

  • *ListObjectsV2Output - The page of results containing:
    • Contents ([]types.Object) - List of objects
    • IsTruncated (*bool) - Set to false if all results were returned, true if more keys available
    • NextContinuationToken (*string) - Continuation token for next page
    • KeyCount (*int32) - Number of keys returned (always ≤ MaxKeys)
    • CommonPrefixes ([]types.CommonPrefix) - Common prefixes if delimiter was specified
    • ContinuationToken (*string) - Continuation token used in request
    • Delimiter (*string) - Delimiter used
    • EncodingType (types.EncodingType) - Encoding type used
    • MaxKeys (*int32) - Maximum keys requested
    • Name (*string) - Bucket name
    • Prefix (*string) - Prefix filter used
    • StartAfter (*string) - StartAfter value used
  • error - Error if the operation fails or if no more pages are available

API Client Interface

type ListObjectsV2APIClient interface {
    ListObjectsV2(context.Context, *ListObjectsV2Input, ...func(*Options)) (*ListObjectsV2Output, error)
}

{ .api }

Usage Example

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/s3"
)

func main() {
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        log.Fatalf("unable to load SDK config, %v", err)
    }

    client := s3.NewFromConfig(cfg)

    // Create paginator with custom page size
    paginator := s3.NewListObjectsV2Paginator(client, &s3.ListObjectsV2Input{
        Bucket:  aws.String("my-bucket"),
        MaxKeys: aws.Int32(500),
        Prefix:  aws.String("photos/2024/"),
    }, func(o *s3.ListObjectsV2PaginatorOptions) {
        o.Limit = 500
        o.StopOnDuplicateToken = true
    })

    // Process all objects
    var totalSize int64
    objectCount := 0

    for paginator.HasMorePages() {
        page, err := paginator.NextPage(context.TODO())
        if err != nil {
            log.Fatalf("failed to get page, %v", err)
        }

        for _, obj := range page.Contents {
            objectCount++
            totalSize += aws.ToInt64(obj.Size)
            fmt.Printf("%s (size: %d bytes, modified: %v)\n",
                *obj.Key, *obj.Size, *obj.LastModified)
        }

        fmt.Printf("Page complete: %d objects\n", len(page.Contents))
    }

    fmt.Printf("\nTotal: %d objects, %d bytes (%.2f MB)\n",
        objectCount, totalSize, float64(totalSize)/(1024*1024))
}

ListPartsPaginator

Paginates results from the ListParts operation, returning parts that have been uploaded for a specific multipart upload.

Constructor

func NewListPartsPaginator(
    client ListPartsAPIClient,
    params *ListPartsInput,
    optFns ...func(*ListPartsPaginatorOptions)
) *ListPartsPaginator

{ .api }

Parameters:

  • client (ListPartsAPIClient) - The S3 client implementing the ListParts operation
  • params (*ListPartsInput) - Input parameters for the ListParts operation
    • Bucket (*string, required) - Bucket name
    • Key (*string, required) - Object key for the multipart upload
    • UploadId (*string, required) - Upload ID identifying the multipart upload
    • MaxParts (*int32) - Maximum number of parts to return per page
    • PartNumberMarker (*string) - Part number marker for pagination
    • ExpectedBucketOwner (*string) - Account ID of expected bucket owner
    • RequestPayer (types.RequestPayer) - Confirms requester pays for request
    • SSECustomerAlgorithm (*string) - Server-side encryption algorithm (for SSE-C)
    • SSECustomerKey (*string) - Server-side encryption customer key (for SSE-C)
    • SSECustomerKeyMD5 (*string) - MD5 of SSE-C key (for SSE-C)
  • optFns (...func(*ListPartsPaginatorOptions)) - Optional configuration functions

Returns: *ListPartsPaginator - A new paginator instance

Options Type

type ListPartsPaginatorOptions struct {
    Limit              int32
    StopOnDuplicateToken bool
}

{ .api }

Fields:

  • Limit (int32) - Maximum number of parts to return per page
  • StopOnDuplicateToken (bool) - If true, pagination stops when the service returns a token matching the most recent token provided

Methods

HasMorePages
func (p *ListPartsPaginator) HasMorePages() bool

{ .api }

Returns true if more pages are available, false otherwise.

NextPage
func (p *ListPartsPaginator) NextPage(
    ctx context.Context,
    optFns ...func(*Options)
) (*ListPartsOutput, error)

{ .api }

Retrieves the next page of results.

Parameters:

  • ctx (context.Context) - Context for cancellation and timeout
  • optFns (...func(*Options)) - Optional per-operation configuration

Returns:

  • *ListPartsOutput - The page of results containing:
    • Parts ([]types.Part) - List of uploaded parts
    • IsTruncated (*bool) - Indicates if list is truncated
    • NextPartNumberMarker (*string) - Part number marker for next page
    • MaxParts (*int32) - Maximum parts allowed in response
    • AbortDate (*time.Time) - Date when upload becomes eligible for abort (lifecycle rule)
    • AbortRuleId (*string) - ID of lifecycle rule defining abort action
    • Bucket (*string) - Bucket name
    • ChecksumAlgorithm (types.ChecksumAlgorithm) - Checksum algorithm used
    • ChecksumType (types.ChecksumType) - Checksum type
    • Initiator (*types.Initiator) - Upload initiator information
    • Key (*string) - Object key
    • Owner (*types.Owner) - Object owner information
    • PartNumberMarker (*string) - Part number marker used in request
    • StorageClass (types.StorageClass) - Storage class
    • UploadId (*string) - Upload ID
  • error - Error if the operation fails or if no more pages are available

API Client Interface

type ListPartsAPIClient interface {
    ListParts(context.Context, *ListPartsInput, ...func(*Options)) (*ListPartsOutput, error)
}

{ .api }

Usage Example

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/s3"
)

func main() {
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        log.Fatalf("unable to load SDK config, %v", err)
    }

    client := s3.NewFromConfig(cfg)

    // Create paginator for listing parts of a multipart upload
    uploadId := "example-upload-id-123456"
    paginator := s3.NewListPartsPaginator(client, &s3.ListPartsInput{
        Bucket:   aws.String("my-bucket"),
        Key:      aws.String("large-file.dat"),
        UploadId: aws.String(uploadId),
        MaxParts: aws.Int32(1000),
    })

    // Iterate through all parts
    var totalSize int64
    partCount := 0

    for paginator.HasMorePages() {
        page, err := paginator.NextPage(context.TODO())
        if err != nil {
            log.Fatalf("failed to get page, %v", err)
        }

        for _, part := range page.Parts {
            partCount++
            totalSize += aws.ToInt64(part.Size)
            fmt.Printf("Part %d: ETag=%s, Size=%d bytes\n",
                aws.ToInt32(part.PartNumber), *part.ETag, *part.Size)
        }
    }

    fmt.Printf("\nTotal: %d parts uploaded, %d bytes (%.2f MB)\n",
        partCount, totalSize, float64(totalSize)/(1024*1024))
}

Waiters

Waiters poll an API operation until a desired state is reached or a timeout occurs. They use exponential backoff between retry attempts.

Common Waiter Pattern

All waiters in the S3 package follow a consistent pattern:

  1. Create a waiter using a constructor function New<State>Waiter
  2. Configure waiter options (delays, retry behavior)
  3. Call Wait() or WaitForOutput() with a maximum wait duration

BucketExistsWaiter

Waits until a bucket exists and is accessible by polling the HeadBucket operation.

Constructor

func NewBucketExistsWaiter(
    client HeadBucketAPIClient,
    optFns ...func(*BucketExistsWaiterOptions)
) *BucketExistsWaiter

{ .api }

Parameters:

  • client (HeadBucketAPIClient) - The S3 client implementing the HeadBucket operation
  • optFns (...func(*BucketExistsWaiterOptions)) - Optional configuration functions

Returns: *BucketExistsWaiter - A new waiter instance

Options Type

type BucketExistsWaiterOptions struct {
    APIOptions      []func(*middleware.Stack) error
    ClientOptions   []func(*Options)
    MinDelay        time.Duration
    MaxDelay        time.Duration
    LogWaitAttempts bool
    Retryable       func(context.Context, *HeadBucketInput, *HeadBucketOutput, error) (bool, error)
}

{ .api }

Fields:

  • APIOptions ([]func(*middleware.Stack) error) - Options to modify how operations are invoked. These apply to all operations invoked by this waiter.
  • ClientOptions ([]func(*Options)) - Functional options to be passed to all operations invoked by this client
  • MinDelay (time.Duration) - Minimum amount of time to delay between retries. Default: 5 seconds. Must be ≤ MaxDelay.
  • MaxDelay (time.Duration) - Maximum amount of time to delay between retries. Default: 120 seconds. Must be ≥ MinDelay.
  • LogWaitAttempts (bool) - Enable logging for waiter retry attempts
  • Retryable (func(context.Context, *HeadBucketInput, *HeadBucketOutput, error) (bool, error)) - Function to override service-defined waiter behavior. Returns (true, nil) for retry state, (false, nil) for success state, or (false, error) for failure state.

Methods

Wait
func (w *BucketExistsWaiter) Wait(
    ctx context.Context,
    params *HeadBucketInput,
    maxWaitDur time.Duration,
    optFns ...func(*BucketExistsWaiterOptions)
) error

{ .api }

Calls the waiter function and blocks until the bucket exists or the maximum wait duration is exceeded.

Parameters:

  • ctx (context.Context) - Context for cancellation
  • params (*HeadBucketInput) - Input parameters for the HeadBucket operation
    • Bucket (*string, required) - Bucket name
    • ExpectedBucketOwner (*string) - Account ID of expected bucket owner
  • maxWaitDur (time.Duration) - Maximum wait duration (required, must be > 0)
  • optFns (...func(*BucketExistsWaiterOptions)) - Optional per-wait configuration

Returns:

  • error - nil if bucket exists, error if timeout exceeded or operation fails
WaitForOutput
func (w *BucketExistsWaiter) WaitForOutput(
    ctx context.Context,
    params *HeadBucketInput,
    maxWaitDur time.Duration,
    optFns ...func(*BucketExistsWaiterOptions)
) (*HeadBucketOutput, error)

{ .api }

Calls the waiter function and returns the output of the successful operation.

Parameters:

  • ctx (context.Context) - Context for cancellation
  • params (*HeadBucketInput) - Input parameters for the HeadBucket operation
  • maxWaitDur (time.Duration) - Maximum wait duration (required, must be > 0)
  • optFns (...func(*BucketExistsWaiterOptions)) - Optional per-wait configuration

Returns:

  • *HeadBucketOutput - Output from successful HeadBucket call containing:
    • BucketRegion (*string) - Region where bucket is located
    • AccessPointAlias (*bool) - Indicates if bucket name is an access point alias
    • BucketArn (*string) - ARN of the S3 bucket (directory buckets only)
    • BucketLocationName (*string) - Zone ID of Availability Zone or Local Zone (directory buckets only)
    • BucketLocationType (types.LocationType) - Type of location where bucket is created (directory buckets only)
  • error - Error if timeout exceeded or operation fails

API Client Interface

type HeadBucketAPIClient interface {
    HeadBucket(context.Context, *HeadBucketInput, ...func(*Options)) (*HeadBucketOutput, error)
}

{ .api }

Wait Behavior

The waiter succeeds when:

  • HeadBucket returns a successful response (HTTP 200)

The waiter retries when:

  • HeadBucket returns NotFound error (HTTP 404)

The waiter fails when:

  • HeadBucket returns any other error
  • Maximum wait duration is exceeded

Usage Example

package main

import (
    "context"
    "fmt"
    "log"
    "time"

    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/s3"
)

func main() {
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        log.Fatalf("unable to load SDK config, %v", err)
    }

    client := s3.NewFromConfig(cfg)
    bucketName := "my-new-bucket"

    // Create the bucket
    fmt.Printf("Creating bucket: %s\n", bucketName)
    _, err = client.CreateBucket(context.TODO(), &s3.CreateBucketInput{
        Bucket: aws.String(bucketName),
    })
    if err != nil {
        log.Fatalf("failed to create bucket, %v", err)
    }

    // Create waiter with custom options
    waiter := s3.NewBucketExistsWaiter(client, func(o *s3.BucketExistsWaiterOptions) {
        o.MinDelay = 2 * time.Second
        o.MaxDelay = 30 * time.Second
        o.LogWaitAttempts = true
    })

    // Wait for bucket to exist (max 2 minutes)
    fmt.Println("Waiting for bucket to exist...")
    err = waiter.Wait(context.TODO(), &s3.HeadBucketInput{
        Bucket: aws.String(bucketName),
    }, 2*time.Minute)

    if err != nil {
        log.Fatalf("bucket did not become available: %v", err)
    }

    fmt.Println("Bucket exists and is accessible!")

    // Alternative: Get output from successful operation
    output, err := waiter.WaitForOutput(context.TODO(), &s3.HeadBucketInput{
        Bucket: aws.String(bucketName),
    }, 2*time.Minute)
    if err != nil {
        log.Fatalf("wait failed: %v", err)
    }

    fmt.Printf("Bucket region: %s\n", *output.BucketRegion)
}

BucketNotExistsWaiter

Waits until a bucket does not exist or is no longer accessible by polling the HeadBucket operation.

Constructor

func NewBucketNotExistsWaiter(
    client HeadBucketAPIClient,
    optFns ...func(*BucketNotExistsWaiterOptions)
) *BucketNotExistsWaiter

{ .api }

Parameters:

  • client (HeadBucketAPIClient) - The S3 client implementing the HeadBucket operation
  • optFns (...func(*BucketNotExistsWaiterOptions)) - Optional configuration functions

Returns: *BucketNotExistsWaiter - A new waiter instance

Options Type

type BucketNotExistsWaiterOptions struct {
    APIOptions      []func(*middleware.Stack) error
    ClientOptions   []func(*Options)
    MinDelay        time.Duration
    MaxDelay        time.Duration
    LogWaitAttempts bool
    Retryable       func(context.Context, *HeadBucketInput, *HeadBucketOutput, error) (bool, error)
}

{ .api }

Fields:

  • APIOptions ([]func(*middleware.Stack) error) - Options to modify how operations are invoked. These apply to all operations invoked by this waiter.
  • ClientOptions ([]func(*Options)) - Functional options to be passed to all operations invoked by this client
  • MinDelay (time.Duration) - Minimum amount of time to delay between retries. Default: 5 seconds. Must be ≤ MaxDelay.
  • MaxDelay (time.Duration) - Maximum amount of time to delay between retries. Default: 120 seconds. Must be ≥ MinDelay.
  • LogWaitAttempts (bool) - Enable logging for waiter retry attempts
  • Retryable (func(context.Context, *HeadBucketInput, *HeadBucketOutput, error) (bool, error)) - Function to override service-defined waiter behavior. Returns (true, nil) for retry state, (false, nil) for success state, or (false, error) for failure state.

Methods

Wait
func (w *BucketNotExistsWaiter) Wait(
    ctx context.Context,
    params *HeadBucketInput,
    maxWaitDur time.Duration,
    optFns ...func(*BucketNotExistsWaiterOptions)
) error

{ .api }

Calls the waiter function and blocks until the bucket does not exist or the maximum wait duration is exceeded.

Parameters:

  • ctx (context.Context) - Context for cancellation
  • params (*HeadBucketInput) - Input parameters for the HeadBucket operation
    • Bucket (*string, required) - Bucket name
    • ExpectedBucketOwner (*string) - Account ID of expected bucket owner
  • maxWaitDur (time.Duration) - Maximum wait duration (required, must be > 0)
  • optFns (...func(*BucketNotExistsWaiterOptions)) - Optional per-wait configuration

Returns:

  • error - nil if bucket does not exist, error if timeout exceeded or operation fails
WaitForOutput
func (w *BucketNotExistsWaiter) WaitForOutput(
    ctx context.Context,
    params *HeadBucketInput,
    maxWaitDur time.Duration,
    optFns ...func(*BucketNotExistsWaiterOptions)
) (*HeadBucketOutput, error)

{ .api }

Calls the waiter function and returns the output of the successful operation.

Parameters:

  • ctx (context.Context) - Context for cancellation
  • params (*HeadBucketInput) - Input parameters for the HeadBucket operation
  • maxWaitDur (time.Duration) - Maximum wait duration (required, must be > 0)
  • optFns (...func(*BucketNotExistsWaiterOptions)) - Optional per-wait configuration

Returns:

  • *HeadBucketOutput - Output from the operation when bucket doesn't exist (typically not used as operation fails with NotFound)
  • error - Error if timeout exceeded or operation fails with non-NotFound error

API Client Interface

type HeadBucketAPIClient interface {
    HeadBucket(context.Context, *HeadBucketInput, ...func(*Options)) (*HeadBucketOutput, error)
}

{ .api }

Wait Behavior

The waiter succeeds when:

  • HeadBucket returns NotFound error (HTTP 404)

The waiter retries when:

  • HeadBucket returns a successful response (HTTP 200)

The waiter fails when:

  • HeadBucket returns any other error (not success, not NotFound)
  • Maximum wait duration is exceeded

Usage Example

package main

import (
    "context"
    "fmt"
    "log"
    "time"

    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/s3"
)

func main() {
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        log.Fatalf("unable to load SDK config, %v", err)
    }

    client := s3.NewFromConfig(cfg)
    bucketName := "bucket-to-delete"

    // Delete the bucket
    fmt.Printf("Deleting bucket: %s\n", bucketName)
    _, err = client.DeleteBucket(context.TODO(), &s3.DeleteBucketInput{
        Bucket: aws.String(bucketName),
    })
    if err != nil {
        log.Fatalf("failed to delete bucket, %v", err)
    }

    // Create waiter with custom retry delays
    waiter := s3.NewBucketNotExistsWaiter(client, func(o *s3.BucketNotExistsWaiterOptions) {
        o.MinDelay = 1 * time.Second
        o.MaxDelay = 10 * time.Second
        o.LogWaitAttempts = true
    })

    // Wait for bucket to be deleted (max 1 minute)
    fmt.Println("Waiting for bucket to be fully deleted...")
    err = waiter.Wait(context.TODO(), &s3.HeadBucketInput{
        Bucket: aws.String(bucketName),
    }, 1*time.Minute)

    if err != nil {
        log.Fatalf("bucket was not deleted: %v", err)
    }

    fmt.Println("Bucket has been successfully deleted!")
}

Advanced Example with Context Timeout

package main

import (
    "context"
    "fmt"
    "log"
    "time"

    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/s3"
)

func main() {
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        log.Fatalf("unable to load SDK config, %v", err)
    }

    client := s3.NewFromConfig(cfg)
    bucketName := "temporary-bucket"

    // Delete bucket
    _, err = client.DeleteBucket(context.TODO(), &s3.DeleteBucketInput{
        Bucket: aws.String(bucketName),
    })
    if err != nil {
        log.Fatalf("failed to delete bucket, %v", err)
    }

    // Create context with timeout
    ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
    defer cancel()

    // Create waiter
    waiter := s3.NewBucketNotExistsWaiter(client)

    // Wait with context timeout
    fmt.Println("Waiting for bucket deletion with 30 second timeout...")
    err = waiter.Wait(ctx, &s3.HeadBucketInput{
        Bucket: aws.String(bucketName),
    }, 30*time.Second)

    if err != nil {
        if ctx.Err() == context.DeadlineExceeded {
            log.Fatal("wait cancelled: context deadline exceeded")
        }
        log.Fatalf("wait failed: %v", err)
    }

    fmt.Println("Bucket no longer exists!")
}

ObjectExistsWaiter

Waits until an object exists and is accessible by polling the HeadObject operation.

Constructor

func NewObjectExistsWaiter(
    client HeadObjectAPIClient,
    optFns ...func(*ObjectExistsWaiterOptions)
) *ObjectExistsWaiter

{ .api }

Parameters:

  • client (HeadObjectAPIClient) - The S3 client implementing the HeadObject operation
  • optFns (...func(*ObjectExistsWaiterOptions)) - Optional configuration functions

Returns: *ObjectExistsWaiter - A new waiter instance

Options Type

type ObjectExistsWaiterOptions struct {
    APIOptions      []func(*middleware.Stack) error
    ClientOptions   []func(*Options)
    MinDelay        time.Duration
    MaxDelay        time.Duration
    LogWaitAttempts bool
    Retryable       func(context.Context, *HeadObjectInput, *HeadObjectOutput, error) (bool, error)
}

{ .api }

Fields:

  • APIOptions ([]func(*middleware.Stack) error) - Options to modify how operations are invoked. These apply to all operations invoked by this waiter.
  • ClientOptions ([]func(*Options)) - Functional options to be passed to all operations invoked by this client
  • MinDelay (time.Duration) - Minimum amount of time to delay between retries. Default: 5 seconds. Must be ≤ MaxDelay.
  • MaxDelay (time.Duration) - Maximum amount of time to delay between retries. Default: 120 seconds. Must be ≥ MinDelay.
  • LogWaitAttempts (bool) - Enable logging for waiter retry attempts
  • Retryable (func(context.Context, *HeadObjectInput, *HeadObjectOutput, error) (bool, error)) - Function to override service-defined waiter behavior. Returns (true, nil) for retry state, (false, nil) for success state, or (false, error) for failure state.

Methods

Wait
func (w *ObjectExistsWaiter) Wait(
    ctx context.Context,
    params *HeadObjectInput,
    maxWaitDur time.Duration,
    optFns ...func(*ObjectExistsWaiterOptions)
) error

{ .api }

Calls the waiter function and blocks until the object exists or the maximum wait duration is exceeded.

Parameters:

  • ctx (context.Context) - Context for cancellation
  • params (*HeadObjectInput) - Input parameters for the HeadObject operation
    • Bucket (*string, required) - Bucket name
    • Key (*string, required) - Object key
    • VersionId (*string) - Object version ID (optional)
    • ExpectedBucketOwner (*string) - Account ID of expected bucket owner
  • maxWaitDur (time.Duration) - Maximum wait duration (required, must be > 0)
  • optFns (...func(*ObjectExistsWaiterOptions)) - Optional per-wait configuration

Returns:

  • error - nil if object exists, error if timeout exceeded or operation fails
WaitForOutput
func (w *ObjectExistsWaiter) WaitForOutput(
    ctx context.Context,
    params *HeadObjectInput,
    maxWaitDur time.Duration,
    optFns ...func(*ObjectExistsWaiterOptions)
) (*HeadObjectOutput, error)

{ .api }

Calls the waiter function and returns the output of the successful operation.

Parameters:

  • ctx (context.Context) - Context for cancellation
  • params (*HeadObjectInput) - Input parameters for the HeadObject operation
  • maxWaitDur (time.Duration) - Maximum wait duration (required, must be > 0)
  • optFns (...func(*ObjectExistsWaiterOptions)) - Optional per-wait configuration

Returns:

  • *HeadObjectOutput - Output from successful HeadObject call containing object metadata
  • error - Error if timeout exceeded or operation fails

API Client Interface

type HeadObjectAPIClient interface {
    HeadObject(context.Context, *HeadObjectInput, ...func(*Options)) (*HeadObjectOutput, error)
}

{ .api }

Wait Behavior

The waiter succeeds when:

  • HeadObject returns a successful response (HTTP 200)

The waiter retries when:

  • HeadObject returns NotFound error (HTTP 404)

The waiter fails when:

  • HeadObject returns any other error
  • Maximum wait duration is exceeded

Usage Example

package main

import (
    "context"
    "fmt"
    "log"
    "time"

    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/s3"
)

func main() {
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        log.Fatalf("unable to load SDK config, %v", err)
    }

    client := s3.NewFromConfig(cfg)
    bucketName := "my-bucket"
    objectKey := "data/file.txt"

    // Upload the object
    fmt.Printf("Uploading object: %s/%s\n", bucketName, objectKey)
    _, err = client.PutObject(context.TODO(), &s3.PutObjectInput{
        Bucket: aws.String(bucketName),
        Key:    aws.String(objectKey),
        Body:   strings.NewReader("Hello, World!"),
    })
    if err != nil {
        log.Fatalf("failed to upload object, %v", err)
    }

    // Create waiter with custom options
    waiter := s3.NewObjectExistsWaiter(client, func(o *s3.ObjectExistsWaiterOptions) {
        o.MinDelay = 1 * time.Second
        o.MaxDelay = 30 * time.Second
        o.LogWaitAttempts = true
    })

    // Wait for object to exist (max 2 minutes)
    fmt.Println("Waiting for object to exist...")
    err = waiter.Wait(context.TODO(), &s3.HeadObjectInput{
        Bucket: aws.String(bucketName),
        Key:    aws.String(objectKey),
    }, 2*time.Minute)

    if err != nil {
        log.Fatalf("object did not become available: %v", err)
    }

    fmt.Println("Object exists and is accessible!")

    // Alternative: Get output from successful operation
    output, err := waiter.WaitForOutput(context.TODO(), &s3.HeadObjectInput{
        Bucket: aws.String(bucketName),
        Key:    aws.String(objectKey),
    }, 2*time.Minute)
    if err != nil {
        log.Fatalf("wait failed: %v", err)
    }

    fmt.Printf("Object size: %d bytes\n", *output.ContentLength)
    fmt.Printf("Last modified: %v\n", *output.LastModified)
}

ObjectNotExistsWaiter

Waits until an object does not exist or is no longer accessible by polling the HeadObject operation.

Constructor

func NewObjectNotExistsWaiter(
    client HeadObjectAPIClient,
    optFns ...func(*ObjectNotExistsWaiterOptions)
) *ObjectNotExistsWaiter

{ .api }

Parameters:

  • client (HeadObjectAPIClient) - The S3 client implementing the HeadObject operation
  • optFns (...func(*ObjectNotExistsWaiterOptions)) - Optional configuration functions

Returns: *ObjectNotExistsWaiter - A new waiter instance

Options Type

type ObjectNotExistsWaiterOptions struct {
    APIOptions      []func(*middleware.Stack) error
    ClientOptions   []func(*Options)
    MinDelay        time.Duration
    MaxDelay        time.Duration
    LogWaitAttempts bool
    Retryable       func(context.Context, *HeadObjectInput, *HeadObjectOutput, error) (bool, error)
}

{ .api }

Fields:

  • APIOptions ([]func(*middleware.Stack) error) - Options to modify how operations are invoked. These apply to all operations invoked by this waiter.
  • ClientOptions ([]func(*Options)) - Functional options to be passed to all operations invoked by this client
  • MinDelay (time.Duration) - Minimum amount of time to delay between retries. Default: 5 seconds. Must be ≤ MaxDelay.
  • MaxDelay (time.Duration) - Maximum amount of time to delay between retries. Default: 120 seconds. Must be ≥ MinDelay.
  • LogWaitAttempts (bool) - Enable logging for waiter retry attempts
  • Retryable (func(context.Context, *HeadObjectInput, *HeadObjectOutput, error) (bool, error)) - Function to override service-defined waiter behavior. Returns (true, nil) for retry state, (false, nil) for success state, or (false, error) for failure state.

Methods

Wait
func (w *ObjectNotExistsWaiter) Wait(
    ctx context.Context,
    params *HeadObjectInput,
    maxWaitDur time.Duration,
    optFns ...func(*ObjectNotExistsWaiterOptions)
) error

{ .api }

Calls the waiter function and blocks until the object does not exist or the maximum wait duration is exceeded.

Parameters:

  • ctx (context.Context) - Context for cancellation
  • params (*HeadObjectInput) - Input parameters for the HeadObject operation
    • Bucket (*string, required) - Bucket name
    • Key (*string, required) - Object key
    • VersionId (*string) - Object version ID (optional)
    • ExpectedBucketOwner (*string) - Account ID of expected bucket owner
  • maxWaitDur (time.Duration) - Maximum wait duration (required, must be > 0)
  • optFns (...func(*ObjectNotExistsWaiterOptions)) - Optional per-wait configuration

Returns:

  • error - nil if object does not exist, error if timeout exceeded or operation fails
WaitForOutput
func (w *ObjectNotExistsWaiter) WaitForOutput(
    ctx context.Context,
    params *HeadObjectInput,
    maxWaitDur time.Duration,
    optFns ...func(*ObjectNotExistsWaiterOptions)
) (*HeadObjectOutput, error)

{ .api }

Calls the waiter function and returns the output of the successful operation.

Parameters:

  • ctx (context.Context) - Context for cancellation
  • params (*HeadObjectInput) - Input parameters for the HeadObject operation
  • maxWaitDur (time.Duration) - Maximum wait duration (required, must be > 0)
  • optFns (...func(*ObjectNotExistsWaiterOptions)) - Optional per-wait configuration

Returns:

  • *HeadObjectOutput - Output from the operation when object doesn't exist (typically not used as operation fails with NotFound)
  • error - Error if timeout exceeded or operation fails with non-NotFound error

API Client Interface

type HeadObjectAPIClient interface {
    HeadObject(context.Context, *HeadObjectInput, ...func(*Options)) (*HeadObjectOutput, error)
}

{ .api }

Wait Behavior

The waiter succeeds when:

  • HeadObject returns NotFound error (HTTP 404)

The waiter retries when:

  • HeadObject returns a successful response (HTTP 200)

The waiter fails when:

  • HeadObject returns any other error (not success, not NotFound)
  • Maximum wait duration is exceeded

Usage Example

package main

import (
    "context"
    "fmt"
    "log"
    "time"

    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/s3"
)

func main() {
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        log.Fatalf("unable to load SDK config, %v", err)
    }

    client := s3.NewFromConfig(cfg)
    bucketName := "my-bucket"
    objectKey := "temp-file.txt"

    // Delete the object
    fmt.Printf("Deleting object: %s/%s\n", bucketName, objectKey)
    _, err = client.DeleteObject(context.TODO(), &s3.DeleteObjectInput{
        Bucket: aws.String(bucketName),
        Key:    aws.String(objectKey),
    })
    if err != nil {
        log.Fatalf("failed to delete object, %v", err)
    }

    // Create waiter with custom retry delays
    waiter := s3.NewObjectNotExistsWaiter(client, func(o *s3.ObjectNotExistsWaiterOptions) {
        o.MinDelay = 1 * time.Second
        o.MaxDelay = 10 * time.Second
        o.LogWaitAttempts = true
    })

    // Wait for object to be deleted (max 1 minute)
    fmt.Println("Waiting for object to be fully deleted...")
    err = waiter.Wait(context.TODO(), &s3.HeadObjectInput{
        Bucket: aws.String(bucketName),
        Key:    aws.String(objectKey),
    }, 1*time.Minute)

    if err != nil {
        log.Fatalf("object was not deleted: %v", err)
    }

    fmt.Println("Object has been successfully deleted!")
}

Advanced Example with Context Timeout

package main

import (
    "context"
    "fmt"
    "log"
    "time"

    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/s3"
)

func main() {
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        log.Fatalf("unable to load SDK config, %v", err)
    }

    client := s3.NewFromConfig(cfg)
    bucketName := "my-bucket"
    objectKey := "temporary-object.dat"

    // Delete object
    _, err = client.DeleteObject(context.TODO(), &s3.DeleteObjectInput{
        Bucket: aws.String(bucketName),
        Key:    aws.String(objectKey),
    })
    if err != nil {
        log.Fatalf("failed to delete object, %v", err)
    }

    // Create context with timeout
    ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
    defer cancel()

    // Create waiter
    waiter := s3.NewObjectNotExistsWaiter(client)

    // Wait with context timeout
    fmt.Println("Waiting for object deletion with 30 second timeout...")
    err = waiter.Wait(ctx, &s3.HeadObjectInput{
        Bucket: aws.String(bucketName),
        Key:    aws.String(objectKey),
    }, 30*time.Second)

    if err != nil {
        if ctx.Err() == context.DeadlineExceeded {
            log.Fatal("wait cancelled: context deadline exceeded")
        }
        log.Fatalf("wait failed: %v", err)
    }

    fmt.Println("Object no longer exists!")
}

Best Practices

Paginators

  1. Always check HasMorePages(): Use the HasMorePages() method in your loop condition to ensure you process all available pages.

  2. Handle errors appropriately: Each call to NextPage() can fail. Handle errors gracefully and consider retry logic for transient failures.

  3. Set appropriate page sizes: Configure the Limit option to balance between number of API calls and memory usage.

  4. Use StopOnDuplicateToken: Enable this option to prevent infinite loops if the API returns duplicate tokens.

  5. Respect API rate limits: Implement exponential backoff if you encounter throttling errors.

  6. Process results incrementally: For very large result sets, process objects as you retrieve each page rather than accumulating all results in memory.

Waiters

  1. Set reasonable timeouts: Choose maxWaitDur values appropriate for your use case. Bucket operations typically complete within minutes.

  2. Configure retry delays: Adjust MinDelay and MaxDelay based on expected operation duration to balance responsiveness and API call frequency.

  3. Use contexts for cancellation: Pass contexts with timeouts or cancellation to enable graceful shutdown.

  4. Enable logging for debugging: Set LogWaitAttempts = true during development to understand wait behavior.

  5. Handle timeout errors: Distinguish between operation failures and timeout expiration in your error handling.

  6. Consider eventual consistency: S3 operations may take time to propagate. Factor in AWS eventual consistency model when setting timeouts.

Error Handling

Paginator Errors

Paginators can return errors from:

  • The underlying API operation (e.g., access denied, bucket not found)
  • Invalid pagination state (e.g., calling NextPage() when no more pages are available)

Example:

paginator := s3.NewListObjectsV2Paginator(client, params)

for paginator.HasMorePages() {
    page, err := paginator.NextPage(ctx)
    if err != nil {
        var nsk *types.NoSuchKey
        var nsb *types.NoSuchBucket

        switch {
        case errors.As(err, &nsb):
            log.Fatal("bucket does not exist")
        case errors.As(err, &nsk):
            log.Fatal("key does not exist")
        default:
            log.Fatalf("failed to get page: %v", err)
        }
    }

    // Process page...
}

Waiter Errors

Waiters can return errors from:

  • The underlying API operation
  • Timeout expiration
  • Context cancellation

Example:

waiter := s3.NewBucketExistsWaiter(client)

err := waiter.Wait(ctx, params, maxDuration)
if err != nil {
    if ctx.Err() == context.DeadlineExceeded {
        log.Fatal("context deadline exceeded")
    }
    if ctx.Err() == context.Canceled {
        log.Fatal("context cancelled")
    }

    // Check if specific S3 error
    var nf *types.NotFound
    if errors.As(err, &nf) {
        log.Fatal("bucket not found")
    }

    log.Fatalf("wait failed: %v", err)
}

Performance Considerations

Paginators

  • Page size: Larger page sizes reduce API calls but increase memory usage and response time per call
  • Parallelization: Process pages concurrently when order doesn't matter (ensure proper synchronization)
  • Streaming: Process objects from each page immediately rather than accumulating all results

Waiters

  • Retry strategy: Exponential backoff balances API call frequency and responsiveness
  • Default delays: MinDelay=5s, MaxDelay=120s provide reasonable defaults for most scenarios
  • Polling overhead: Each wait attempt makes an API call; consider the cumulative cost for long waits

Related Documentation

  • AWS SDK for Go v2 S3 Client Documentation
  • S3 API Reference
  • AWS SDK for Go v2 Documentation
  • S3 Best Practices