Skip to main content

MinIO SDK

MinIO Go Client SDK is the official library for Go that allows you to work with S3-compatible storages using the Amazon S3 API (S3 API).

Configure the MinIO SDK

  1. Set up access to S3.
  2. Install the library in your project.
  3. Set environment variables.
  4. Configure the client.

1. Set up access to S3

Access can be configured by the Account Owner or a user with the iam.admin role.

  1. Create a service user with a role with access to S3. If you use a service user with the s3.user, object_storage_user or s3.bucket.user role, the bucket must have a configured access policy and its rules must allow access to this user.
  2. Issue an S3 key to the user.

2. Install the library

  1. Open the CLI.

  2. Add the library to your project:

    go get github.com/minio/minio-go/v7

3. Set environment variables

Various methods for specifying S3 keys are available. We recommend specifying S3 keys via environment variables rather than in code. Learn more about other methods in the MinIO SDK documentation.

  1. Open the CLI.

  2. Set the variables:

    export AWS_ACCESS_KEY_ID=<access_key>
    export AWS_SECRET_ACCESS_KEY=<secret_key>

    Specify:

    • <access_key> — value of the Access key field from the S3 key that you obtained in Step 1;
    • <secret_key> — value of the Secret key field from the S3 key that you obtained in Step 1.

4. Configure the client

  1. In your local project, open the main.go file.

  2. Add the client initialization script:

    package main

    import (
    "context"
    "log"
    "github.com/minio/minio-go/v7"
    "github.com/minio/minio-go/v7/pkg/credentials"
    )

    func main() {

    creds := credentials.NewEnvAWS()

    endpoint := "<s3_domain>"

    minioClient, err := minio.New(endpoint, &minio.Options{
    Creds: creds,
    Secure: true,
    })
    if err != nil {
    log.Fatal(err)
    }

    }

    Specify <s3_domain> — S3 API domain. The domain depends on the pool where S3 is located.

Working with MinIO SDK

If errors occur while working with MinIO SDK, check the list of possible errors.

Get a list of buckets

  1. Open the main.go file with the client that you configured in Step 4, or create a new file and copy the client into it.

  2. In the func main() block, add a script to get a list of buckets:

    info, err := minioClient.ListBuckets(context.Background())
    if err != nil {
    log.Fatalf("cannot get ListBuckets: %s", err)
    }

    log.Printf("%#v\n", info)
    Example of the full script
    package main

    import (
    "context"
    "log"
    "github.com/minio/minio-go/v7"
    "github.com/minio/minio-go/v7/pkg/credentials"
    )

    func main() {

    creds := credentials.NewEnvAWS()

    endpoint := "<s3_domain>"

    minioClient, err := minio.New(endpoint, &minio.Options{
    Creds: creds,
    Secure: true,
    })
    if err != nil {
    log.Fatal(err)
    }

    info, err := minioClient.ListBuckets(context.Background())
    if err != nil {
    log.Fatalf("cannot get ListBuckets: %s", err)
    }

    log.Printf("%#v\n", info)

    }

    Where <s3_domain> is the S3 API domain. The domain depends on the pool where S3 is located.

Create a bucket

  1. Open the main.go file with the client that you configured in Step 4, or create a new file and copy the client into it.

  2. In the func main() block, add a script to create a bucket:

    bucketName := "<bucket_name>"

    err = minioClient.MakeBucket(
    context.Background(),
    bucketName,
    minio.MakeBucketOptions{Region: "<pool>"},
    )
    if err != nil {
    exists, errBucketExists := minioClient.BucketExists(context.Background(), bucketName)
    if errBucketExists == nil && exists {
    log.Printf("Bucket %s already exists", bucketName)
    } else {
    log.Fatalf("cannot create bucket: %s", err)
    }
    } else {
    log.Printf("Bucket %s created", bucketName)
    }

    Specify:

    • optional: <pool> — pool where the bucket will be created;
    • <bucket_name> — bucket name.
    Example of the full script
    package main

    import (
    "context"
    "log"

    "github.com/minio/minio-go/v7"
    "github.com/minio/minio-go/v7/pkg/credentials"
    )

    func main() {

    creds := credentials.NewEnvAWS()

    endpoint := "<s3_domain>"

    minioClient, err := minio.New(endpoint, &minio.Options{
    Creds: creds,
    Secure: true,
    })
    if err != nil {
    log.Fatal(err)
    }

    bucketName := "bucketName"

    err = minioClient.MakeBucket(
    context.Background(),
    bucketName,
    minio.MakeBucketOptions{Region: "ru-7"},
    )
    if err != nil {
    exists, errBucketExists := minioClient.BucketExists(context.Background(), bucketName)
    if errBucketExists == nil && exists {
    log.Printf("Bucket %s already exists", bucketName)
    } else {
    log.Fatalf("cannot create bucket: %s", err)
    }
    } else {
    log.Printf("Bucket %s created", bucketName)
    }
    }

    Where <s3_domain> is the S3 API domain. The domain depends on the pool where S3 is located.

Upload an object to a bucket

  1. Open the main.go file with the client that you configured in Step 4, or create a new file and copy the client into it.

  2. In the func main() block, add a script to upload an object to the bucket:

    objectName := "<object_name>"
    filePath := "<path>"
    contentType := "application/octet-stream"

    info, err := minioClient.FPutObject(
    context.Background(),
    "<bucket_name>",
    objectName,
    filePath,
    minio.PutObjectOptions{ContentType: contentType},
    )
    if err != nil {
    log.Fatalf("Error: %s", err)
    }

    log.Printf("File uploaded. Size: %d bytes", info.Size)

    Specify:

    • <object_name> — name that the object will have in S3;
    • <path> — path to the file on the local device;
    • <bucket_name> — bucket name.
    Example of the full script
    package main

    import (
    "context"
    "log"
    "github.com/minio/minio-go/v7"
    "github.com/minio/minio-go/v7/pkg/credentials"
    )

    func main() {

    creds := credentials.NewEnvAWS()

    endpoint := "<s3_domain>"

    minioClient, err := minio.New(endpoint, &minio.Options{
    Creds: creds,
    Secure: true,
    })
    if err != nil {
    log.Fatal(err)
    }

    objectName := "object-name.csv"
    filePath := "/path/file.csv"
    contentType := "application/octet-stream"

    info, err := minioClient.FPutObject(
    context.Background(),
    "bucketName",
    objectName,
    filePath,
    minio.PutObjectOptions{ContentType: contentType},
    )
    if err != nil {
    log.Fatalf("Error: %s", err)
    }

    log.Printf("File uploaded. Size: %d bytes", info.Size)
    }

    Where <s3_domain> is the S3 API domain. The domain depends on the pool where S3 is located.

Get a list of objects in a bucket

  1. Open the main.go file with the client that you configured in Step 4, or create a new file and copy the client into it.

  2. In the func main() block, add a script to get a list of objects in the bucket:

    objectsChan := minioClient.ListObjects(context.TODO(), "<bucket_name>", minio.ListObjectsOptions{
    Recursive: true,
    })
    for object := range objectsChan {
    log.Printf("%#v\n", object)
    }

    Specify <bucket_name> — bucket name.

    Example of the full script
    package main

    import (
    "context"
    "log"
    "github.com/minio/minio-go/v7"
    "github.com/minio/minio-go/v7/pkg/credentials"
    )

    func main() {

    creds := credentials.NewEnvAWS()

    endpoint := "<s3_domain>"

    minioClient, err := minio.New(endpoint, &minio.Options{
    Creds: creds,
    Secure: true,
    })
    if err != nil {
    log.Fatal(err)
    }

    objectsChan := minioClient.ListObjects(context.TODO(), "bucketName", minio.ListObjectsOptions{
    Recursive: true,
    })
    for object := range objectsChan {
    log.Printf("%#v\n", object)
    }
    }

    Where <s3_domain> is the S3 API domain. The domain depends on the pool where S3 is located.

Change the versioning status in a bucket

  1. Open the main.go file with the client that you configured in Step 4, or create a new file and copy the client into it.

  2. In the func main() block, add a script to change the versioning status:

    err = minioClient.SetBucketVersioning(
    context.Background(),
    "<bucket_name>",
    minio.BucketVersioningConfiguration{Status: "<status>"},
    )
    if err != nil {
    log.Fatalf("cannot enable versioning: %s", err)
    }
    log.Printf("Versioning enabled for bucket %s", "<bucket_name>")

    Specify:

    • <bucket_name> — bucket name;

    • <status> — versioning status to set on the bucket. Possible values:

      • Enabled — enable versioning;
      • Suspended — suspend versioning.
    Example of the full script
    package main

    import (
    "context"
    "log"

    "github.com/minio/minio-go/v7"
    "github.com/minio/minio-go/v7/pkg/credentials"
    )

    func main() {

    creds := credentials.NewEnvAWS()

    endpoint := "<s3_domain>"

    minioClient, err := minio.New(endpoint, &minio.Options{
    Creds: creds,
    Secure: true,
    })
    if err != nil {
    log.Fatal(err)
    }

    bucketName := "bucketName"

    err = minioClient.SetBucketVersioning(
    context.Background(),
    bucketName,
    minio.BucketVersioningConfiguration{Status: "Enabled"},
    )
    if err != nil {
    log.Fatalf("cannot enable versioning: %s", err)
    }

    log.Printf("Versioning enabled for bucket %s", bucketName)
    }

    Where <s3_domain> is the S3 API domain. The domain depends on the pool where S3 is located.

  3. Optional: in the func main() block, add a script to check the versioning status:

    bucketName := "<bucket_name>"

    config, err := minioClient.GetBucketVersioning(context.Background(), bucketName)
    if err != nil {
    log.Fatalf("cannot get versioning config: %s", err)
    }

    log.Printf("Versioning status: %s", config.Status)

    Specify <bucket_name> — bucket name.

Get an object

  1. Open the main.go file with the client that you configured in Step 4, or create a new file and copy the client into it.

  2. In the import block, add the io package:

    import (
    "context"
    "log"
    "io"
    "github.com/minio/minio-go/v7"
    "github.com/minio/minio-go/v7/pkg/credentials"
    )
  3. In the func main() block, add a script to get an object:

    object, err := minioClient.GetObject(context.TODO(), "<bucket_name>", "<object_name>", minio.GetObjectOptions{})
    if err != nil {
    log.Fatalf("cannot get object: %s", err)
    }

    log.Printf("%#v\n", object)

    byteSlice, err := io.ReadAll(object)
    if err != nil {
    log.Fatalf("Error reading from reader: %s\n", err)
    }

    log.Printf("object contains: \"%s\"", byteSlice)

    Specify:

    • <object_name> — object name;
    • <bucket_name> — bucket name.
    Example of the full script
    package main

    import (
    "context"
    "log"
    "io"
    "github.com/minio/minio-go/v7"
    "github.com/minio/minio-go/v7/pkg/credentials"
    )

    func main() {

    creds := credentials.NewEnvAWS()

    endpoint := "<s3_domain>"

    minioClient, err := minio.New(endpoint, &minio.Options{
    Creds: creds,
    Secure: true,
    })
    if err != nil {
    log.Fatal(err)
    }

    object, err := minioClient.GetObject(context.TODO(), "bucketName", "objectName", minio.GetObjectOptions{})
    if err != nil {
    log.Fatalf("cannot get object: %s", err)
    }

    log.Printf("%#v\n", object)

    byteSlice, err := io.ReadAll(object)
    if err != nil {
    log.Fatalf("Error reading from reader: %s\n", err)
    }

    log.Printf("object contains: \"%s\"", byteSlice)
    }

    Where <s3_domain> is the S3 API domain. The domain depends on the pool where S3 is located.

You can create a link in a public or private bucket using a presigned URL. Learn more about Presigned URLs in the Sharing objects with presigned URLs guide of the AWS documentation.

  1. Open the main.go file with the client that you configured in Step 4, or create a new file and copy the client into it.

  2. In the import block, add the time package.

    import (
    "context"
    "log"
    "time"

    "github.com/minio/minio-go/v7"
    "github.com/minio/minio-go/v7/pkg/credentials"
    )
  3. In the func main() block, add a script to create upload and download links:

    getURL, err := minioClient.PresignedGetObject(
    context.Background(),
    "<bucket_name>",
    "<object_name>",
    <expiry>,
    nil,
    )
    if err != nil {
    log.Fatalf("cannot generate presigned get url: %s", err)
    }
    log.Printf("Presigned GET URL: %s", getURL.String())

    putURL, err := minioClient.PresignedPutObject(
    context.Background(),
    "<bucket_name>",
    "<object_name>",
    <expiry>,
    )
    if err != nil {
    log.Fatalf("cannot generate presigned put url: %s", err)
    }
    log.Printf("Presigned PUT URL: %s", putURL.String())

    Specify:

    • <bucket_name> — bucket name;

    • <object_name> — object name;

    • <expiry> — link validity period in the <amount>*<time> format, where:

      • <amount> — number of hours, minutes, or seconds the link will remain valid;
      • <time> — time unit, possible values: time.Hour, time.Minute, or time.Second.
    Example of the full script
    package main

    import (
    "context"
    "log"
    "time"

    "github.com/minio/minio-go/v7"
    "github.com/minio/minio-go/v7/pkg/credentials"
    )

    func main() {

    creds := credentials.NewEnvAWS()

    endpoint := "<s3_domain>"

    minioClient, err := minio.New(endpoint, &minio.Options{
    Creds: creds,
    Secure: true,
    })
    if err != nil {
    log.Fatal(err)
    }

    getURL, err := minioClient.PresignedGetObject(
    context.Background(),
    "bucketName",
    "objectName",
    30*time.Hour,
    nil,
    )
    if err != nil {
    log.Fatalf("cannot generate presigned get url: %s", err)
    }
    log.Printf("Presigned GET URL: %s", getURL.String())

    putURL, err := minioClient.PresignedPutObject(
    context.Background(),
    "bucketName",
    "objectName",
    time.Hour,
    )
    if err != nil {
    log.Fatalf("cannot generate presigned put url: %s", err)
    }
    log.Printf("Presigned PUT URL: %s", putURL.String())
    }

    Where <s3_domain> is the S3 API domain. The domain depends on the pool where S3 is located.

Get object metadata

  1. Open the main.go file with the client that you configured in Step 4, or create a new file and copy the client into it.

  2. In the func main() block, add a script to get object metadata:

    info, err := minioClient.StatObject(
    context.Background(),
    "<bucket_name>",
    "<object_name>",
    minio.StatObjectOptions{},
    )
    if err != nil {
    log.Fatalf("cannot get object info: %s", err)
    }

    log.Printf("Key: %s", info.Key)
    log.Printf("Size: %d bytes", info.Size)
    log.Printf("ContentType: %s", info.ContentType)
    log.Printf("ETag: %s", info.ETag)
    log.Printf("LastModified: %s", info.LastModified)

    Specify:

    • <bucket_name> — bucket name;
    • <object_name> — object name.
    Example of the full script
    package main

    import (
    "context"
    "log"

    "github.com/minio/minio-go/v7"
    "github.com/minio/minio-go/v7/pkg/credentials"
    )

    func main() {

    creds := credentials.NewEnvAWS()

    endpoint := "<s3_domain>"

    minioClient, err := minio.New(endpoint, &minio.Options{
    Creds: creds,
    Secure: true,
    })
    if err != nil {
    log.Fatal(err)
    }

    info, err := minioClient.StatObject(
    context.Background(),
    "bucketName",
    "objectName",
    minio.StatObjectOptions{},
    )
    if err != nil {
    log.Fatalf("cannot get object info: %s", err)
    }

    log.Printf("Key: %s", info.Key)
    log.Printf("Size: %d bytes", info.Size)
    log.Printf("ContentType: %s", info.ContentType)
    log.Printf("ETag: %s", info.ETag)
    log.Printf("LastModified: %s", info.LastModified)
    }

    Where <s3_domain> is the S3 API domain. The domain depends on the pool where S3 is located.

Delete an object

  1. Open the main.go file with the client that you configured in Step 4, or create a new file and copy the client into it.

  2. In the func main() block, add a script to delete an object:

    err = minioClient.RemoveObject(
    context.Background(),
    "<bucket_name>",
    "<object_name>",
    minio.RemoveObjectOptions{VersionID: "<version_id>"},
    )
    if err != nil {
    log.Fatalf("cannot remove object: %s", err)
    }
    log.Printf("Object %s removed", "<object_name>")

    Specify:

    • <bucket_name> — bucket name;
    • <object_name> — object name;
    • optional: VersionID: "<version_id>" — option that deletes a specific version of the object if versioning is enabled in the bucket. Specify <version_id> — version ID.
    Example of the full script
    package main

    import (
    "context"
    "log"

    "github.com/minio/minio-go/v7"
    "github.com/minio/minio-go/v7/pkg/credentials"
    )

    func main() {

    creds := credentials.NewEnvAWS()

    endpoint := "<s3_domain>"

    minioClient, err := minio.New(endpoint, &minio.Options{
    Creds: creds,
    Secure: true,
    })
    if err != nil {
    log.Fatal(err)
    }

    err = minioClient.RemoveObject(
    context.Background(),
    "bucketName",
    "objectName",
    minio.RemoveObjectOptions{},
    )
    if err != nil {
    log.Fatalf("cannot remove object: %s", err)
    }

    log.Printf("Object %s removed", "objectName")
    }

    Where <s3_domain> is the S3 API domain. The domain depends on the pool where S3 is located.

Possible errors

ErrorDescriptionSolution
AccessDeniedAccess deniedCheck keys, access policies, and user permissions
NoSuchBucketBucket does not existCheck the bucket name and target pool
NoSuchKeyObject not foundCheck the object name and its path in the bucket
BucketAlreadyExistsA bucket with this name already existsSpecify a different name
BucketNotEmptyBucket is not emptyDelete all objects and uncompleted uploads before deleting the bucket
InvalidBucketNameInvalid bucket nameSpecify a name that contains only lowercase letters, numbers, dots, and hyphens
connection refusedIncorrect S3 API domainMake sure that the domain matches the pool where the bucket is located
SignatureDoesNotMatchThe signature does not match: invalid secret key or corrupted request headersUse a valid secret key and check the request headers
MalformedXMLMalformed XMLCheck the syntax and structure of the passed XML
TooManyBucketsBucket limit reached. Delete unused buckets or request a quota increase
RequestTimeoutRequest timed out. Check the network connection or increase the request timeout
MethodNotAllowedAn invalid HTTP method is used for this operation (GET/PUT/DELETE)