

AWS SDK for Go V1 has reached end-of-support. We recommend that you migrate to [AWS SDK for Go V2](https://docs.aws.amazon.com/sdk-for-go/v2/developer-guide/). For additional details and information on how to migrate, please refer to this [announcement](https://aws.amazon.com/blogs//developer/announcing-end-of-support-for-aws-sdk-for-go-v1-on-july-31-2025/).

# Configuring the AWS SDK for Go
Configuring the SDK

In the AWS SDK for Go, you can configure settings for service clients, such as the log level and maximum number of retries. Most settings are optional. However, for each service client, you must specify an AWS Region and your credentials. The SDK uses these values to send requests to the correct Region and sign requests with the correct credentials. You can specify these values as part of a session or as environment variables.

## Creating a Session


Before you can create a service client you must create a session, which is part of the `github.com/aws/aws-sdk-go/aws/session` package.

There are a number of ways of configuring a session but the following are the most common.

Create a session using the default Region and credentials:

```
import (
    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/session"
)

// ...

sess := session.Must(session.NewSessionWithOptions(session.Options{
    SharedConfigState: session.SharedConfigEnable,
}))
```

Create a session in **us-west-2**:

```
import (
    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/session"
)

// ...

sess, err := session.NewSession(&aws.Config{
    Region: aws.String("us-west-2")},
)
```

See [session](https://docs.aws.amazon.com/sdk-for-go/api/aws/session) for additional information.

## Specifying the AWS Region


When you specify the Region, you specify where to send requests, such as `us-west-2` or `us-east-2.` For a list of Regions for each service, see [Service endpoints and quotas](https://docs.aws.amazon.com/general/latest/gr/aws-service-information.html) in the Amazon Web Services General Reference.

The SDK does not have a default Region. To specify a Region:
+ Set the `AWS_REGION` environment variable to the default Region
+ Set the `AWS_SDK_LOAD_CONFIG` environment variable to **true** to get the Region value from the *config* file in the `.aws/` folder in your home directory
+ Set the **NewSessionWithOptions** method argument **SharedConfigState** to **SharedConfigEnable** when you create a session to get the Region value from the *config* file in the `.aws/` folder in your home directory
+ Set the Region explicitly when you create a session

If you set a Region using all of these techniques, the SDK uses the Region you explicitly specified in the session.

The following examples show you how to configure the environment variable.

 **Linux, OS X, or Unix** 

```
$ export AWS_REGION=us-west-2
```

 **Windows** 

```
> set AWS_REGION=us-west-2
```

The following snippet specifies the Region in a session:

```
sess, err := session.NewSession(&aws.Config{Region: aws.String("us-west-2")})
```

## Specifying Credentials


The AWS SDK for Go requires credentials (an access key and secret access key) to sign requests to AWS. You can specify your credentials in several different locations, depending on your particular use case. For information about obtaining credentials, see [Setting Up](setting-up.md).

When you initialize a new service client without providing any credential arguments, the SDK uses the [default credential provider chain](https://docs.aws.amazon.com/sdk-for-go/api/aws/defaults/#CredChain) to find AWS credentials. The SDK uses the first provider in the chain that returns credentials without an error. The default provider chain looks for credentials in the following order:

1. Environment variables.

1. Shared credentials file.

1. If your application uses an ECS task definition or RunTask API operation, IAM role for tasks.

1. If your application is running on an Amazon EC2 instance, IAM role for Amazon EC2.

The SDK detects and uses the built-in providers automatically, without requiring manual configurations. For example, if you use IAM roles for Amazon EC2 instances, your applications automatically use the instance’s credentials. You don’t need to manually configure credentials in your application.

As a best practice, AWS recommends that you specify credentials in the following order:

1. Use IAM roles for tasks if your application uses an ECS task definition or RunTask API operation.

1. Use IAM roles for Amazon EC2 (if your application is running on an Amazon EC2 instance).

   IAM roles provide applications on the instance temporary security credentials to make AWS calls. IAM roles provide an easy way to distribute and manage credentials on multiple Amazon EC2 instances.

1. Use a shared credentials file.

   This credentials file is the same one used by other SDKs and the AWS CLI. If you’re already using a shared credentials file, you can also use it for this purpose.

1. Use environment variables.

   Setting environment variables is useful if you’re doing development work on a machine other than an Amazon EC2 instance.

### IAM Roles for Tasks


If your application uses an Amazon ECS task definition or `RunTask` operation, use [IAM Roles for Tasks](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-iam-roles.html) to specify an IAM role that can be used by the containers in a task.

### IAM Roles for Amazon EC2 Instances


If you are running your application on an Amazon EC2 instance, use the instance’s [IAM role](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html) to get temporary security credentials to make calls to AWS.

If you have configured your instance to use IAM roles, the SDK uses these credentials for your application automatically. You don’t need to manually specify these credentials.

### Shared Credentials File


A credential file is a plaintext file that contains your access keys. The file must be on the same machine on which you’re running your application. The file must be named `credentials` and located in the `.aws/` folder in your home directory. The home directory can vary by operating system. In Windows, you can refer to your home directory by using the environment variable `%UserProfile%`. In Unix-like systems, you can use the environment variable `$HOME` or `~` (tilde).

If you already use this file for other SDKs and tools (like the AWS CLI), you don’t need to change anything to use the files in this SDK. If you use different credentials for different tools or applications, you can use *profiles* to configure multiple access keys in the same configuration file.

#### Creating the Credentials File


If you don’t have a shared credentials file (`.aws/credentials`), you can use any text editor to create one in your home directory. Add the following content to your credentials file, replacing `<YOUR_ACCESS_KEY_ID>` and `<YOUR_SECRET_ACCESS_KEY>` with your credentials.

```
[default]
aws_access_key_id = <YOUR_ACCESS_KEY_ID>
aws_secret_access_key = <YOUR_SECRET_ACCESS_KEY>
```

The `[default]` heading defines credentials for the default profile, which the SDK will use unless you configure it to use another profile.

You can also use temporary security credentials by adding the session tokens to your profile, as shown in the following example:

```
[temp]
aws_access_key_id = <YOUR_TEMP_ACCESS_KEY_ID>
aws_secret_access_key = <YOUR_TEMP_SECRET_ACCESS_KEY>
aws_session_token = <YOUR_SESSION_TOKEN>
```

#### Specifying Profiles


You can include multiple access keys in the same configuration file by associating each set of access keys with a profile. For example, in your credentials file, you can declare multiple profiles, as follows.

```
[default]
aws_access_key_id = <YOUR_DEFAULT_ACCESS_KEY_ID>
aws_secret_access_key = <YOUR_DEFAULT_SECRET_ACCESS_KEY>

[test-account]
aws_access_key_id = <YOUR_TEST_ACCESS_KEY_ID>
aws_secret_access_key = <YOUR_TEST_SECRET_ACCESS_KEY>

[prod-account]
; work profile
aws_access_key_id = <YOUR_PROD_ACCESS_KEY_ID>
aws_secret_access_key = <YOUR_PROD_SECRET_ACCESS_KEY>
```

By default, the SDK checks the `AWS_PROFILE` environment variable to determine which profile to use. If no `AWS_PROFILE` variable is set, the SDK uses the default profile.

If you have an application named `myapp` that uses the SDK, you can run it with the test credentials by setting the variable to `test-account myapp`, as shown in the following command.

```
$ AWS_PROFILE=test-account myapp
```

You can also use the SDK to select a profile by specifying `os.Setenv("AWS_PROFILE", test-account)` before constructing any service clients or by manually setting the credential provider, as shown in the following example.

```
sess, err := session.NewSession(&aws.Config{
    Region:      aws.String("us-west-2"),
    Credentials: credentials.NewSharedCredentials("", "test-account"),
})
```

In addition, checking if your credentials have been found is fairly easy.

```
_, err := sess.Config.Credentials.Get()
```

If `ChainProvider` is being used, set `CredentialsChainVerboseErrors` to `true` in the session config.

**Note**  
If you specify credentials in environment variables, the SDK will always use those credentials, no matter which profile you specify.

### Environment Variables


By default, the SDK detects AWS credentials set in your environment and uses them to sign requests to AWS. That way you don’t need to manage credentials in your applications.

The SDK looks for credentials in the following environment variables:
+  `AWS_ACCESS_KEY_ID` 
+  `AWS_SECRET_ACCESS_KEY` 
+  `AWS_SESSION_TOKEN` (optional)

The following examples show how you configure the environment variables.

 **Linux, OS X, or Unix** 

```
$ export AWS_ACCESS_KEY_ID=YOUR_AKID
$ export AWS_SECRET_ACCESS_KEY=YOUR_SECRET_KEY
$ export AWS_SESSION_TOKEN=TOKEN
```

 **Windows** 

```
> set AWS_ACCESS_KEY_ID=YOUR_AKID
> set AWS_SECRET_ACCESS_KEY=YOUR_SECRET_KEY
> set AWS_SESSION_TOKEN=TOKEN
```

### Hard-Coded Credentials in an Application (Not Recommended)


**Warning**  
Do not embed credentials inside an application. Use this method only for testing purposes.

You can hard-code credentials in your application by passing the access keys to a configuration instance, as shown in the following snippet.

```
sess, err := session.NewSession(&aws.Config{
    Region:      aws.String("us-west-2"),
    Credentials: credentials.NewStaticCredentials("AKID", "SECRET_KEY", "TOKEN"),
})
```

### Other Credentials Providers


The SDK provides other methods for retrieving credentials in the `aws/credentials` package. For example, you can retrieve temporary security credentials from AWS Security Token Service or credentials from encrypted storage. For more information, see [Credentials](https://docs.aws.amazon.com/sdk-for-go/api/aws/credentials/).

## Configuring a Proxy


If you cannot directly connect to the internet, you can use Go-supported environment variables (`HTTP_PROXY`) or create a custom HTTP client to configure your proxy. Use the [Config.HTTPClient](https://docs.aws.amazon.com/sdk-for-go/api/aws/#Config.WithHTTPClient) struct to specify a custom HTTP client. For more information about how to create an HTTP client to use a proxy, see the [Transport](https://golang.org/pkg/net/http/#Transport) struct in the Go `http` package.

## Logging Service Calls


You can enable logging in a client by setting the `LogLevel` in a configuration instance, as shown in the following snippet, which sets the log level to `LogDebugWithHTTPBody` for a new DynamoDB client.

```
svc := dynamodb.New(sess, aws.NewConfig().WithLogLevel(aws.LogDebugWithHTTPBody))
```

See [LogLevelType](https://docs.aws.amazon.com/sdk-for-go/api/aws/#LogLevelType) for the different log level values.

## Creating a Custom Endpoint


In most cases you use the endpoint that is pre-configured for a service. However, you can specify a custom endpoint, such as for pre-release versions of the service, as shown in the following snippet, which sets the `Endpoint` to `https://test.us-west-2.amazonaws.com` for a new DynamoDB client.

```
svc := dynamodb.New(sess, &aws.Config{Endpoint: aws.String("https://test.us-west-2.amazonaws.com")})
```

See [aws.Config](https://docs.aws.amazon.com/sdk-for-go/api/aws/#Config) for details.

**Topics**

# Creating a Custom HTTP Client
Custom HTTP Client

The AWS SDK for Go uses a default HTTP client with default configuration values. Although you can change some of these configuration values, the default HTTP client and transport are not sufficiently configurable for customers using the AWS SDK for Go in an environment with high throughput and low latency requirements. This section describes how to create a custom HTTP client, and use that client to create AWS SDK for Go calls.

To assist you in creating a custom HTTP client, this section describes how to create a structure to encapsulate the custom settings, create a function to create a custom HTTP client based on those settings, and use that custom HTTP client to call an AWS SDK for Go service client.

Let’s define what we want to customize.

## Dialer.KeepAlive


This setting represents the keep-alive period for an active network connection.

Set to a negative value to disable keep-alives.

Set to **0** to enable keep-alives if supported by the protocol and operating system.

Network protocols or operating systems that do not support keep-alives ignore this field. By default, TCP enables keep alive.

See [https://golang.org/pkg/net/\$1Dialer.KeepAlive](https://golang.org/pkg/net/#Dialer.KeepAlive) 

We’ll call this `ConnKeepAlive` as **time.Duration**.

## Dialer.Timeout


This setting represents the maximum amount of time a dial to wait for a connection to be created.

Default is 30 seconds.

See [https://golang.org/pkg/net/\$1Dialer.Timeout](https://golang.org/pkg/net/#Dialer.Timeout) 

We’ll call this `Connect` as **time.Duration**.

## Transport.ExpectContinueTimeout


This setting represents the maximum amount of time to wait for a server’s first response headers after fully writing the request headers, if the request has an “Expect: 100-continue” header. This time does not include the time to send the request header. The HTTP client sends its payload after this timeout is exhausted.

Default 1 second.

Set to **0** for no timeout and send request payload without waiting. One use case is when you run into issues with proxies or third party services that take a session similar to the use of Amazon S3 in the function shown later.

See [https://golang.org/pkg/net/http/\$1Transport.ExpectContinueTimeout](https://golang.org/pkg/net/http/#Transport.ExpectContinueTimeout) 

We’ll call this `ExpectContinue` as **time.Duration**.

## Transport.IdleConnTimeout


This setting represents the maximum amount of time to keep an idle network connection alive between HTTP requests.

Set to **0** for no limit.

See [https://golang.org/pkg/net/http/\$1Transport.IdleConnTimeout](https://golang.org/pkg/net/http/#Transport.IdleConnTimeout) 

We’ll call this `IdleConn` as **time.Duration**.

## Transport.MaxIdleConns


This setting represents the maximum number of idle (keep-alive) connections across all hosts. One use case for increasing this value is when you are seeing many connections in a short period from the same clients

 **0** means no limit.

See [https://golang.org/pkg/net/http/\$1Transport.MaxIdleConns](https://golang.org/pkg/net/http/#Transport.MaxIdleConns) 

We’ll call this `MaxAllIdleConns` as **int**.

## Transport.MaxIdleConnsPerHost


This setting represents the maximum number of idle (keep-alive) connections to keep per-host. One use case for increasing this value is when you are seeing many connections in a short period from the same clients

Default is two idle connections per host.

Set to **0** to use DefaultMaxIdleConnsPerHost (2).

See [https://golang.org/pkg/net/http/\$1Transport.MaxIdleConnsPerHost](https://golang.org/pkg/net/http/#Transport.MaxIdleConnsPerHost) 

We’ll call this `MaxHostIdleConns` as **int**.

## Transport.ResponseHeaderTimeout


This setting represents the maximum amount of time to wait for a client to read the response header.

If the client isn’t able to read the response’s header within this duration, the request fails with a timeout error.

Be careful setting this value when using long-running Lambda functions, as the operation does not return any response headers until the Lambda function has finished or timed out. However, you can still use this option with the **InvokeAsync** API operation.

Default is no timeout; wait forever.

See [https://golang.org/pkg/net/http/\$1Transport.ResponseHeaderTimeout](https://golang.org/pkg/net/http/#Transport.ResponseHeaderTimeout) 

We’ll call this `ResponseHeader` as **time.Duration**.

## Transport.TLSHandshakeTimeout


This setting represents the maximum amount of time waiting for a TLS handshake to be completed.

Default is 10 seconds.

Zero means no timeout.

See [https://golang.org/pkg/net/http/\$1Transport.TLSHandshakeTimeout](https://golang.org/pkg/net/http/#Transport.TLSHandshakeTimeout) 

We’ll call this `TLSHandshake` as **time.Duration**.

## Create Import Statement


The complete example imports the following Go packages.

```
import (
    "bytes"
    "context"
    "flag"
    "fmt"
    "io"
    "net"
    "net/http"
    "time"

    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/s3"

    "golang.org/x/net/http2"
)
```

## Creating a Timeout Struct


Let’s create a struct to hold the timeout values we want to be able to set on our HTTP client.

```
type HTTPClientSettings struct {
    Connect          time.Duration
    ConnKeepAlive    time.Duration
    ExpectContinue   time.Duration
    IdleConn         time.Duration
    MaxAllIdleConns  int
    MaxHostIdleConns int
    ResponseHeader   time.Duration
    TLSHandshake     time.Duration
}
```

## Creating a Function to Create a Custom HTTP Client


Next let’s create a function that takes a **ClientTimeout** struct and creates a custom HTTP client based on those timeout values.

```
func NewHTTPClientWithSettings(httpSettings HTTPClientSettings) (*http.Client, error) {
    var client http.Client
    tr := &http.Transport{
        ResponseHeaderTimeout: httpSettings.ResponseHeader,
        Proxy:                 http.ProxyFromEnvironment,
        DialContext: (&net.Dialer{
            KeepAlive: httpSettings.ConnKeepAlive,
            DualStack: true,
            Timeout:   httpSettings.Connect,
        }).DialContext,
        MaxIdleConns:          httpSettings.MaxAllIdleConns,
        IdleConnTimeout:       httpSettings.IdleConn,
        TLSHandshakeTimeout:   httpSettings.TLSHandshake,
        MaxIdleConnsPerHost:   httpSettings.MaxHostIdleConns,
        ExpectContinueTimeout: httpSettings.ExpectContinue,
    }

    // So client makes HTTP/2 requests
    err := http2.ConfigureTransport(tr)
    if err != nil {
        return &client, err
    }

    return &http.Client{
        Transport: tr,
    }, nil
}
```

## Using a Custom HTTP Client


Let’s create a custom HTTP client and use it to create an Amazon S3 client.

The following example creates an **http.Client** that is configured to have:
+ a five second TCP connection timeout
+ a five second TLS handshake timeout
+ a five second wait for the HTTP response headers

```
httpClient, err := NewHTTPClientWithSettings(HTTPClientSettings{
    Connect:          5 * time.Second,
    ExpectContinue:   1 * time.Second,
    IdleConn:         90 * time.Second,
    ConnKeepAlive:    30 * time.Second,
    MaxAllIdleConns:  100,
    MaxHostIdleConns: 10,
    ResponseHeader:   5 * time.Second,
    TLSHandshake:     5 * time.Second,
})
if err != nil {
    fmt.Println("Got an error creating custom HTTP client:")
    fmt.Println(err)
    return
}

sess := session.Must(session.NewSession(&aws.Config{
    HTTPClient: httpClient,
}))

svc := s3.New(sess)
```

All of these settings give the client approximately 15 seconds create a connection, do a TLS handshake, and receive the response headers from the service. The time that the client takes to read the response body is not covered by these timeouts. To specify a total timeout for the request to include reading the response body, use the AWS SDK for Go client’s **WithContext** API operation methods, such as the Amazon S3 operation [PutObjectWithContext](https://docs.aws.amazon.com/sdk-for-go/api/service/s3/#S3.PutObjectWithContext) with a **context.Withtimeout**.

The following example uses a timeout context to limit the total time an API request can be active to a maximum of 20 seconds. The SDK must be able to read the full HTTP response body (Object body) within the timeout or the SDK returns a timeout error. For API operations that return an **io.ReadCloser** in their response type, the Context’s timeout includes reading the content from the **io.ReadCloser**.

```
ctx, cancelFn := context.WithTimeout(context.TODO(), 20*time.Second)
defer cancelFn()

resp, err := svc.GetObjectWithContext(ctx, &s3.GetObjectInput{
    Bucket: bucket,
    Key:    object,
})
if err != nil {
    return body, err
}

return resp.Body, nil
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/go/s3/CustomClient/CustomHttpClient.go) on GitHub.