-
Notifications
You must be signed in to change notification settings - Fork 633
Description
Checkboxes for prior research
- I've gone through Developer Guide and API reference
- I've checked AWS Forums and StackOverflow.
- I've searched for previous similar issues and didn't find any solution.
Describe the bug
Bug Report: @aws-sdk/client-s3
Times Out on Windows with VPN DNS Override
Is this a bug report or a feature request?
Bug Report
Package Name:
@aws-sdk/client-s3
SDK Version:
"@aws-sdk/client-s3": "^3.883.0"
Node.js Version:
v24.7.0
OS:
Windows 11
Describe the bug
The @aws-sdk/client-s3
client fails to establish a network connection and times out when running on Windows under a specific network configuration created by common VPN clients like Tailscale. The failure occurs when the VPN is configured to override the system's DNS servers but is not routing all traffic through a full tunnel (i.e., no "exit node" is active).

Regression Issue
- Select this option if this issue appears to be a regression.
SDK version number
@aws-sdk/[email protected]
Which JavaScript Runtime is this issue in?
Node.js
Details of the browser/Node.js/ReactNative version
v24.7.0
Reproduction Steps
-
Set up the Environment:
- OS: Windows 11
- Node.js: v24.7.0 or similar.
- VPN Client: Install a client that can override system DNS, such as Tailscale.
-
Configure the Failing Network State:
- Connect the VPN client.
- Enable the feature that forces all system DNS queries to go through the VPN's specified nameservers.
- Crucially, ensure that an "exit node" or "full tunnel" is disabled. Only DNS traffic should be captured by the VPN's virtual adapter.
-
Prepare the Reproducer Script:
- Create a new directory.
- Run
npm init -y
. - Run
npm install @aws-sdk/client-s3
. - Create a file
reproduce-bug.js
with the code below.
-
Run the Test:
- Execute
node reproduce-bug.js
. The script will time out. - For validation, disable the VPN's DNS override feature and run the script again. It will succeed immediately with an authentication error.
- Execute
Logs
Failing Case (VPN DNS Override Enabled):
Attempting to make a request using the AWS S3 SDK...
Creating S3 client...
S3 client created.
Sending GetObjectCommand to S3 endpoint...
--- TEST FINISHED WITH AN ERROR ---
Error Name: TimeoutError
Error Message: The request timed out.
CONCLUSION: NETWORK FAILURE! BUG REPRODUCED!
The script failed to establish a connection with the server. This indicates a low-level networking issue in the SDK.
Working Case (Standard Network / VPN DNS Override Disabled):
Attempting to make a request using the AWS S3 SDK...
Creating S3 client...
S3 client created.
Sending GetObjectCommand to S3 endpoint...
--- TEST FINISHED WITH AN ERROR ---
Error Name: InvalidAccessKeyId
Error Message: The AWS Access Key Id you provided does not exist in our records.
CONCLUSION: NETWORK SUCCESS!
The script successfully connected to the server, which correctly rejected the dummy credentials.
Minimal Reproducer Code (reproduce-bug.js
)
// Minimal reproducer for a network failure in the AWS SDK v3 client
// when operating under specific VPN DNS configurations on Windows.
const { S3Client, GetObjectCommand } = require('@aws-sdk/client-s3');
// --- Configuration ---
// These details point to a public Backblaze B2 bucket.
const BUCKET_NAME = 'mybucket33';
const OBJECT_KEY = 'info.json';
const ENDPOINT_URL = 'https://s3.eu-central-003.backblazeb2.com';
const REGION = 'eu-central-003';
async function main() {
console.log('Attempting to make a request using the AWS S3 SDK...');
const s3Client = new S3Client({
region: REGION,
endpoint: ENDPOINT_URL,
forcePathStyle: true,
credentials: {
// Dummy credentials are used intentionally.
// A successful network connection should result in an "InvalidAccessKeyId" error.
// A timeout or generic network error indicates the bug has been reproduced.
accessKeyId: 'DUMMY_KEY_ID',
secretAccessKey: 'DUMMY_SECRET_KEY',
},
});
console.log('Sending GetObjectCommand to S3 endpoint...');
const command = new GetObjectCommand({
Bucket: BUCKET_NAME,
Key: OBJECT_KEY,
});
try {
// Set a reasonable timeout for the request.
const response = await s3Client.send(command, { requestTimeout: 15000 });
console.log('UNEXPECTED SUCCESS: The server responded. Status:', response.$metadata.httpStatusCode);
console.log('\nCONCLUSION: NETWORK SUCCESS!');
} catch (error) {
console.error('\n--- TEST FINISHED WITH AN ERROR ---');
console.error('Error Name:', error.name);
console.error('Error Message:', error.message);
if (error.name === 'InvalidAccessKeyId' || error.name === 'SignatureDoesNotMatch' || error.name === 'AccessDenied') {
console.log('\nCONCLUSION: NETWORK SUCCESS!');
console.log('The script successfully connected to the server, which correctly rejected the dummy credentials.');
} else {
console.log('\nCONCLUSION: NETWORK FAILURE! BUG REPRODUCED!');
console.log('The script failed to establish a connection with the server. This indicates a low-level networking issue in the SDK.');
}
}
}
main();
Observed Behavior
Current behavior
The S3 client send()
command hangs for the duration of the request timeout and then fails with a TimeoutError
. No connection is ever established with the server.
Expected behavior
The S3 client should successfully establish a network connection to the S3 endpoint, regardless of which network interface handled the DNS resolution. Given dummy credentials, the expected behavior is a fast failure with an authentication error from the server (e.g., InvalidAccessKeyId
).
Possible Solution
No response
Additional Information/Context
When configuring Tailscale to use an Exit node (the full default route goes through the VPN) the S3 connection works.