@@ -160,6 +160,9 @@ public function registerSessionHandler(array $config = [])
160160 public static function _applyRetryConfig ($ value , array &$ args , HandlerList $ list , string $ service = 'dynamodb ' )
161161 {
162162 if ($ value ) {
163+ // Determine if max_attempts was explicitly provided by the user
164+ // before unwrapping loses that information.
165+ $ maxAttemptsExplicit = self ::isMaxAttemptsExplicit ($ value );
163166 $ config = \Aws \Retry \ConfigurationProvider::unwrap ($ value );
164167
165168 if ($ config ->getMode () === 'legacy ' ) {
@@ -182,8 +185,8 @@ function ($retries) {
182185 );
183186 } else {
184187 // Default to 4 max attempts for DynamoDB/DynamoDB Streams
185- // when no explicit max attempts is configured
186- if ($ config -> getMaxAttempts () === \ Aws \ Retry \ConfigurationProvider:: DEFAULT_MAX_ATTEMPTS ) {
188+ // when max_attempts was not explicitly configured by the user.
189+ if (! $ maxAttemptsExplicit ) {
187190 $ config = new \Aws \Retry \Configuration (
188191 $ config ->getMode (),
189192 4
@@ -204,6 +207,51 @@ function ($retries) {
204207 }
205208 }
206209
210+ /**
211+ * Determines whether max_attempts was explicitly provided by the user
212+ * by inspecting the raw retry config value before unwrapping.
213+ *
214+ * @param mixed $value The raw retry config value
215+ * @return bool
216+ */
217+ private static function isMaxAttemptsExplicit (mixed $ value ): bool
218+ {
219+ // ConfigurationInterface: user explicitly constructed a config object
220+ if ($ value instanceof \Aws \Retry \ConfigurationInterface) {
221+ return true ;
222+ }
223+
224+ // Array with 'max_attempts' key: user explicitly set max_attempts
225+ if (is_array ($ value ) && isset ($ value ['max_attempts ' ])) {
226+ return true ;
227+ }
228+
229+ // Integer: legacy format where the int IS the retries count (explicit)
230+ if (is_int ($ value )) {
231+ return true ;
232+ }
233+
234+ // Callable or CacheInterface: came from a provider chain (env, ini, fallback)
235+ // — max_attempts may have been set via env var or config file
236+ if (is_callable ($ value ) || $ value instanceof \Aws \CacheInterface) {
237+ return self ::isMaxAttemptsFromProvider ($ value );
238+ }
239+
240+ return false ;
241+ }
242+
243+ /**
244+ * Checks if max_attempts was explicitly set via environment variable
245+ * or config file by inspecting the provider chain result.
246+ *
247+ * @param mixed $value The callable or CacheInterface provider
248+ * @return bool
249+ */
250+ private static function isMaxAttemptsFromProvider (mixed $ value ): bool
251+ {
252+ return !empty (getenv (\Aws \Retry \ConfigurationProvider::ENV_MAX_ATTEMPTS ));
253+ }
254+
207255 /** @internal */
208256 public static function _applyApiProvider ($ value , array &$ args , HandlerList $ list )
209257 {
0 commit comments