From 044ee67bda9580c44328f41a99712e4e0089de27 Mon Sep 17 00:00:00 2001 From: Richard Wang Date: Thu, 29 Jan 2026 12:23:57 -0800 Subject: [PATCH 1/3] Improve error message for providers --- .../lib/aws-sdk-core/ecs_credentials.rb | 14 +++++++++++-- .../instance_profile_credentials.rb | 18 +++++++++++++---- .../spec/aws/ecs_credentials_spec.rb | 18 +++++++++++++++++ .../aws/instance_profile_credentials_spec.rb | 20 +++++++++++++++++++ 4 files changed, 64 insertions(+), 6 deletions(-) diff --git a/gems/aws-sdk-core/lib/aws-sdk-core/ecs_credentials.rb b/gems/aws-sdk-core/lib/aws-sdk-core/ecs_credentials.rb index 6c18f128c4d..2f6243af0da 100644 --- a/gems/aws-sdk-core/lib/aws-sdk-core/ecs_credentials.rb +++ b/gems/aws-sdk-core/lib/aws-sdk-core/ecs_credentials.rb @@ -15,7 +15,17 @@ class ECSCredentials include RefreshingCredentials # @api private - class Non200Response < RuntimeError; end + class Non200Response < RuntimeError + attr_reader :status_code, :body + + def initialize(status_code, body = nil) + @status_code = status_code + @body = body + msg = "HTTP #{status_code}" + msg += ": #{body[0..200]}" if body && !body.empty? + super(msg) + end + end # Raised when the token file cannot be read. class TokenFileReadError < RuntimeError; end @@ -251,7 +261,7 @@ def http_get(connection, path) request = Net::HTTP::Get.new(path) set_authorization_token(request) response = connection.request(request) - raise Non200Response unless response.code.to_i == 200 + raise Non200Response.new(response.code.to_i, response.body) unless response.code.to_i == 200 response.body end diff --git a/gems/aws-sdk-core/lib/aws-sdk-core/instance_profile_credentials.rb b/gems/aws-sdk-core/lib/aws-sdk-core/instance_profile_credentials.rb index 338d76812b5..2f3d87eb1e0 100644 --- a/gems/aws-sdk-core/lib/aws-sdk-core/instance_profile_credentials.rb +++ b/gems/aws-sdk-core/lib/aws-sdk-core/instance_profile_credentials.rb @@ -26,7 +26,17 @@ class InstanceProfileCredentials include RefreshingCredentials # @api private - class Non200Response < RuntimeError; end + class Non200Response < RuntimeError + attr_reader :status_code, :body + + def initialize(status_code, body = nil) + @status_code = status_code + @body = body + msg = "HTTP #{status_code}" + msg += ": #{body[0..200]}" if body && !body.empty? + super(msg) + end + end # @api private class TokenRetrivalError < RuntimeError; end @@ -249,7 +259,7 @@ def fetch_credentials(conn) # The next retry should fetch it @token = nil @imds_v1_fallback = false - raise Non200Response + raise Non200Response.new(401, 'Token expired') end def token_set? @@ -278,7 +288,7 @@ def http_get(connection, path) when 401 raise TokenExpiredError else - raise Non200Response + raise Non200Response.new(response.code.to_i, response.body) end end @@ -298,7 +308,7 @@ def http_put(connection) when 400 raise TokenRetrivalError else - raise Non200Response + raise Non200Response.new(response.code.to_i, response.body) end end diff --git a/gems/aws-sdk-core/spec/aws/ecs_credentials_spec.rb b/gems/aws-sdk-core/spec/aws/ecs_credentials_spec.rb index 8c963c0d1d0..0d28aa5a67f 100644 --- a/gems/aws-sdk-core/spec/aws/ecs_credentials_spec.rb +++ b/gems/aws-sdk-core/spec/aws/ecs_credentials_spec.rb @@ -122,6 +122,24 @@ module Aws ECSCredentials.new end.to raise_error(ArgumentError, /without a credential path/) end + + it 'returns empty credentials on non-200 response with error details' do + stub_request(:get, "http://169.254.170.2#{path}") + .to_return(status: 429, body: 'Rate limit exceeded') + expect_any_instance_of(ECSCredentials).to receive(:warn) + .with(/Error retrieving ECS Credentials: HTTP 429: Rate limit exceeded/) + c = ECSCredentials.new(backoff: 0, retries: 0) + expect(c.set?).to be(false) + end + + it 'returns empty credentials on non-200 response without body' do + stub_request(:get, "http://169.254.170.2#{path}") + .to_return(status: 500, body: '') + expect_any_instance_of(ECSCredentials).to receive(:warn) + .with(/Error retrieving ECS Credentials: HTTP 500/) + c = ECSCredentials.new(backoff: 0, retries: 0) + expect(c.set?).to be(false) + end end context 'retries' do diff --git a/gems/aws-sdk-core/spec/aws/instance_profile_credentials_spec.rb b/gems/aws-sdk-core/spec/aws/instance_profile_credentials_spec.rb index 9d60d1b9896..0e644accc75 100644 --- a/gems/aws-sdk-core/spec/aws/instance_profile_credentials_spec.rb +++ b/gems/aws-sdk-core/spec/aws/instance_profile_credentials_spec.rb @@ -451,6 +451,26 @@ module Aws expect(c.credentials.session_token).to be(nil) expect(c.expiration).to be(nil) end + + it 'returns empty credentials on non-200 response from profile endpoint' do + stub_request(:get, "#{ipv4_endpoint_creds_path}profile-name") + .with(headers: { 'x-aws-ec2-metadata-token' => 'my-token' }) + .to_return(status: 404, body: 'Not Found') + expect_any_instance_of(InstanceProfileCredentials).to receive(:warn) + .with(/Error retrieving instance profile credentials: HTTP 404: Not Found/) + c = InstanceProfileCredentials.new(backoff: 0, retries: 0) + expect(c.set?).to be(false) + end + + it 'returns empty credentials on non-200 response from metadata service' do + stub_request(:get, ipv4_endpoint + path) + .with(headers: { 'x-aws-ec2-metadata-token' => 'my-token' }) + .to_return(status: 503, body: 'Service Unavailable') + expect_any_instance_of(InstanceProfileCredentials).to receive(:warn) + .with(/Error retrieving instance profile credentials: HTTP 503: Service Unavailable/) + c = InstanceProfileCredentials.new(backoff: 0, retries: 0) + expect(c.set?).to be(false) + end end end From 0aa9db7f82b2d981d0501444d896738d2fc66380 Mon Sep 17 00:00:00 2001 From: Richard Wang Date: Thu, 29 Jan 2026 12:26:48 -0800 Subject: [PATCH 2/3] Changelog --- gems/aws-sdk-core/CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gems/aws-sdk-core/CHANGELOG.md b/gems/aws-sdk-core/CHANGELOG.md index 19ccc9d90c3..4355c7330c4 100644 --- a/gems/aws-sdk-core/CHANGELOG.md +++ b/gems/aws-sdk-core/CHANGELOG.md @@ -1,6 +1,8 @@ Unreleased Changes ------------------ +* Feature - Include HTTP status code and body in errors whehn retrieving ECS credentials and Instance Profile credentials. + 3.241.4 (2026-01-16) ------------------ From 8b0b5dc115ea678e1736813eae6ac7364eebfb90 Mon Sep 17 00:00:00 2001 From: Richard Wang Date: Thu, 29 Jan 2026 12:59:11 -0800 Subject: [PATCH 3/3] Remove truncation --- gems/aws-sdk-core/lib/aws-sdk-core/ecs_credentials.rb | 2 +- .../lib/aws-sdk-core/instance_profile_credentials.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gems/aws-sdk-core/lib/aws-sdk-core/ecs_credentials.rb b/gems/aws-sdk-core/lib/aws-sdk-core/ecs_credentials.rb index 2f6243af0da..a593e9dbbce 100644 --- a/gems/aws-sdk-core/lib/aws-sdk-core/ecs_credentials.rb +++ b/gems/aws-sdk-core/lib/aws-sdk-core/ecs_credentials.rb @@ -22,7 +22,7 @@ def initialize(status_code, body = nil) @status_code = status_code @body = body msg = "HTTP #{status_code}" - msg += ": #{body[0..200]}" if body && !body.empty? + msg += ": #{body}" if body && !body.empty? super(msg) end end diff --git a/gems/aws-sdk-core/lib/aws-sdk-core/instance_profile_credentials.rb b/gems/aws-sdk-core/lib/aws-sdk-core/instance_profile_credentials.rb index 2f3d87eb1e0..d75ffe15649 100644 --- a/gems/aws-sdk-core/lib/aws-sdk-core/instance_profile_credentials.rb +++ b/gems/aws-sdk-core/lib/aws-sdk-core/instance_profile_credentials.rb @@ -33,7 +33,7 @@ def initialize(status_code, body = nil) @status_code = status_code @body = body msg = "HTTP #{status_code}" - msg += ": #{body[0..200]}" if body && !body.empty? + msg += ": #{body}" if body && !body.empty? super(msg) end end