diff -pruN 1.27.0-2/CHANGELOG.md 1.27.1-1/CHANGELOG.md
--- 1.27.0-2/CHANGELOG.md	2025-08-11 10:03:27.000000000 +0000
+++ 1.27.1-1/CHANGELOG.md	2025-09-08 07:05:54.000000000 +0000
@@ -2,6 +2,12 @@
 
 ## NOT RELEASED
 
+## 1.27.1
+
+### Fixed
+
+- SignerV4: fix sort of query parameters to build correct canoncal query string 
+
 ## 1.27.0
 
 ### Added
diff -pruN 1.27.0-2/debian/changelog 1.27.1-1/debian/changelog
--- 1.27.0-2/debian/changelog	2025-08-24 08:44:50.000000000 +0000
+++ 1.27.1-1/debian/changelog	2025-09-09 05:52:40.000000000 +0000
@@ -1,3 +1,13 @@
+php-async-aws-core (1.27.1-1) unstable; urgency=medium
+
+  [ DmytroVyshnevsky1 ]
+  * fix query params sorting to build correct canonical query string (#1938)
+
+  [ Jérémy Derussé ]
+  * prepare next release
+
+ -- David Prévot <taffit@debian.org>  Tue, 09 Sep 2025 07:52:40 +0200
+
 php-async-aws-core (1.27.0-2) unstable; urgency=medium
 
   * Fix warning with recent PHPUnit
diff -pruN 1.27.0-2/debian/patches/0002-Make-provider-functions-static-PHPUnit-11-Fix.patch 1.27.1-1/debian/patches/0002-Make-provider-functions-static-PHPUnit-11-Fix.patch
--- 1.27.0-2/debian/patches/0002-Make-provider-functions-static-PHPUnit-11-Fix.patch	2025-08-20 06:37:22.000000000 +0000
+++ 1.27.1-1/debian/patches/0002-Make-provider-functions-static-PHPUnit-11-Fix.patch	2025-09-09 05:52:40.000000000 +0000
@@ -6,14 +6,13 @@ Bug-Debian: https://bugs.debian.org/1070
 ---
  tests/HttpClient/AwsRetryStrategyTest.php  | 2 +-
  tests/Unit/ConfigurationTest.php           | 2 +-
- tests/Unit/Signer/SignerV4Test.php         | 2 +-
  tests/Unit/Stream/CallableStreamTest.php   | 6 +++---
  tests/Unit/Stream/FixedSizeStreamTest.php  | 6 +++---
  tests/Unit/Stream/IterableStreamTest.php   | 6 +++---
  tests/Unit/Stream/ResourceStreamTest.php   | 6 +++---
  tests/Unit/Stream/RewindableStreamTest.php | 6 +++---
  tests/Unit/Stream/StringStreamTest.php     | 6 +++---
- 9 files changed, 21 insertions(+), 21 deletions(-)
+ 8 files changed, 20 insertions(+), 20 deletions(-)
 
 diff --git a/tests/HttpClient/AwsRetryStrategyTest.php b/tests/HttpClient/AwsRetryStrategyTest.php
 index a242b23..bccae03 100644
@@ -41,19 +40,6 @@ index e076a82..c5b96ca 100644
      {
          yield 'simple config' => [['endpoint' => 'foo'], [], ['endpoint' => 'foo']];
          yield 'empty config' => [['endpoint' => ''], [], ['endpoint' => '']];
-diff --git a/tests/Unit/Signer/SignerV4Test.php b/tests/Unit/Signer/SignerV4Test.php
-index 495dfb7..fe42964 100644
---- a/tests/Unit/Signer/SignerV4Test.php
-+++ b/tests/Unit/Signer/SignerV4Test.php
-@@ -78,7 +78,7 @@ class SignerV4Test extends TestCase
-         self::assertEquals($expected, $request);
-     }
- 
--    public function provideRequests()
-+    public static function provideRequests()
-     {
-         return [
-             // POST headers should be signed.
 diff --git a/tests/Unit/Stream/CallableStreamTest.php b/tests/Unit/Stream/CallableStreamTest.php
 index fb14d53..dcfce89 100644
 --- a/tests/Unit/Stream/CallableStreamTest.php
diff -pruN 1.27.0-2/debian/patches/0003-Compatibility-with-recent-PHPUnit-12.patch 1.27.1-1/debian/patches/0003-Compatibility-with-recent-PHPUnit-12.patch
--- 1.27.0-2/debian/patches/0003-Compatibility-with-recent-PHPUnit-12.patch	2025-08-20 06:37:22.000000000 +0000
+++ 1.27.1-1/debian/patches/0003-Compatibility-with-recent-PHPUnit-12.patch	2025-09-09 05:52:40.000000000 +0000
@@ -5,14 +5,14 @@ Subject: Compatibility with recent PHPUn
 ---
  tests/HttpClient/AwsRetryStrategyTest.php  | 2 ++
  tests/Unit/ConfigurationTest.php           | 2 ++
- tests/Unit/Signer/SignerV4Test.php         | 3 ++-
+ tests/Unit/Signer/SignerV4Test.php         | 4 +++-
  tests/Unit/Stream/CallableStreamTest.php   | 4 ++++
  tests/Unit/Stream/FixedSizeStreamTest.php  | 5 +++++
  tests/Unit/Stream/IterableStreamTest.php   | 4 ++++
  tests/Unit/Stream/ResourceStreamTest.php   | 4 ++++
  tests/Unit/Stream/RewindableStreamTest.php | 4 ++++
  tests/Unit/Stream/StringStreamTest.php     | 4 ++++
- 9 files changed, 31 insertions(+), 1 deletion(-)
+ 9 files changed, 32 insertions(+), 1 deletion(-)
 
 diff --git a/tests/HttpClient/AwsRetryStrategyTest.php b/tests/HttpClient/AwsRetryStrategyTest.php
 index bccae03..0315729 100644
@@ -55,7 +55,7 @@ index c5b96ca..90fb5b1 100644
      {
          foreach ($env as $key => $value) {
 diff --git a/tests/Unit/Signer/SignerV4Test.php b/tests/Unit/Signer/SignerV4Test.php
-index fe42964..e6218ca 100644
+index 18acb93..328beb3 100644
 --- a/tests/Unit/Signer/SignerV4Test.php
 +++ b/tests/Unit/Signer/SignerV4Test.php
 @@ -9,6 +9,7 @@ use AsyncAws\Core\Request;
@@ -82,6 +82,14 @@ index fe42964..e6218ca 100644
              ],
              // DateHeader should be kept
              [
+@@ -143,6 +144,7 @@ class SignerV4Test extends TestCase
+     /**
+      * @dataProvider provideRequestsWithQueryParams
+      */
++    #[DataProvider('provideRequestsWithQueryParams')]
+     public function testSignsRequestsWithArrayInQueryParams($rawRequestWithoutQuery, $rawExpected, $queryParams)
+     {
+         $request = $this->parseRequest($rawRequestWithoutQuery, $queryParams);
 diff --git a/tests/Unit/Stream/CallableStreamTest.php b/tests/Unit/Stream/CallableStreamTest.php
 index dcfce89..0c5af79 100644
 --- a/tests/Unit/Stream/CallableStreamTest.php
diff -pruN 1.27.0-2/debian/tests/control 1.27.1-1/debian/tests/control
--- 1.27.0-2/debian/tests/control	2024-07-06 11:14:51.000000000 +0000
+++ 1.27.1-1/debian/tests/control	2025-09-09 05:52:40.000000000 +0000
@@ -1,3 +1,3 @@
-Restrictions: rw-build-tree, allow-stderr
+Restrictions: allow-stderr, rw-build-tree
 Depends: phpab, phpunit, pkg-php-tools, @
 Test-Command: mkdir -p vendor && phpabtpl --require async-aws/core > debian/autoload.tests.php.tpl && phpab -o vendor/autoload.php -t debian/autoload.tests.php.tpl tests && phpunit --exclude-group network
diff -pruN 1.27.0-2/phpunit.xml.dist 1.27.1-1/phpunit.xml.dist
--- 1.27.0-2/phpunit.xml.dist	2025-08-11 10:03:27.000000000 +0000
+++ 1.27.1-1/phpunit.xml.dist	2025-09-08 07:05:54.000000000 +0000
@@ -1,17 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd"
-         backupGlobals="false"
-         colors="true"
-         bootstrap="vendor/autoload.php"
-         failOnRisky="true"
-         failOnWarning="true"
->
-  <coverage>
-    <include>
-      <directory>./src</directory>
-    </include>
-  </coverage>
+<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd" backupGlobals="false" colors="true" bootstrap="vendor/autoload.php" failOnRisky="true" failOnWarning="true">
   <php>
     <ini name="error_reporting" value="-1"/>
   </php>
@@ -20,4 +8,9 @@
       <directory>./tests/</directory>
     </testsuite>
   </testsuites>
+  <source>
+    <include>
+      <directory>./src</directory>
+    </include>
+  </source>
 </phpunit>
diff -pruN 1.27.0-2/src/Signer/SignerV4.php 1.27.1-1/src/Signer/SignerV4.php
--- 1.27.0-2/src/Signer/SignerV4.php	2025-08-11 10:03:27.000000000 +0000
+++ 1.27.1-1/src/Signer/SignerV4.php	2025-09-08 07:05:54.000000000 +0000
@@ -321,7 +321,9 @@ class SignerV4 implements Signer
             return '';
         }
 
-        ksort($query);
+        uksort($query, static function (string $a, string $b): int {
+            return strcmp(rawurlencode($a), rawurlencode($b));
+        });
         $encodedQuery = [];
         foreach ($query as $key => $values) {
             if (!\is_array($values)) {
diff -pruN 1.27.0-2/tests/Unit/Signer/SignerV4Test.php 1.27.1-1/tests/Unit/Signer/SignerV4Test.php
--- 1.27.0-2/tests/Unit/Signer/SignerV4Test.php	2025-08-11 10:03:27.000000000 +0000
+++ 1.27.1-1/tests/Unit/Signer/SignerV4Test.php	2025-09-08 07:05:54.000000000 +0000
@@ -78,7 +78,7 @@ class SignerV4Test extends TestCase
         self::assertEquals($expected, $request);
     }
 
-    public function provideRequests()
+    public static function provideRequests()
     {
         return [
             // POST headers should be signed.
@@ -140,7 +140,58 @@ class SignerV4Test extends TestCase
         ];
     }
 
-    private function parseRequest(string $req): Request
+    /**
+     * @dataProvider provideRequestsWithQueryParams
+     */
+    public function testSignsRequestsWithArrayInQueryParams($rawRequestWithoutQuery, $rawExpected, $queryParams)
+    {
+        $request = $this->parseRequest($rawRequestWithoutQuery, $queryParams);
+
+        $signer = new SignerV4('host', 'us-east-1');
+        $context = new RequestContext(['currentDate' => new \DateTimeImmutable('20110909T233600Z')]);
+        $credentials = new Credentials('AKIDEXAMPLE', 'wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY');
+
+        $signer->sign($request, $credentials, $context);
+
+        $expected = $this->parseRequest($rawExpected, $queryParams);
+
+        self::assertEquals($expected, $request);
+    }
+
+    public static function provideRequestsWithQueryParams()
+    {
+        return [
+            // GET Case with array in query params
+            [
+                "GET / HTTP/1.1\r\nHost: host.foo.com:443\r\n\r\n",
+                "GET / HTTP/1.1\r\nHost: host.foo.com:443\r\nX-Amz-Date: 20110909T233600Z\r\nAuthorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=host;x-amz-date, Signature=7bd9c6fed0473be1f7ea96ff34c7d79e71a92932054a24b4210b3a56e4ab46d3\r\n\r\n",
+                [
+                    'foos[0]' => '834127',
+                    'foos[1]' => '59',
+                    'foos[2]' => '90123',
+                    'foos[3]' => '4708',
+                    'foos[4]' => '120001',
+                    'foos[5]' => '333',
+                    'foos[6]' => '78005',
+                    'foos[7]' => '2',
+                    'foos[8]' => 'string value',
+                    'foos[9]' => '40617',
+                    'foos[10]' => '715',
+                ],
+            ],
+            // GET Simple case with query params (copy of one of the cases above from testSignsRequests)
+            [
+                "GET / HTTP/1.1\r\nHost: host.foo.com:443\r\n\r\n",
+                "GET / HTTP/1.1\r\nHost: host.foo.com:443\r\nX-Amz-Date: 20110909T233600Z\r\nAuthorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=host;x-amz-date, Signature=1c3274381ae12d8817336268d7da17672bd57e7348e39b7b9c567280f73742af\r\n\r\n",
+                [
+                    'a' => 'foo',
+                    'b' => 'foo',
+                ],
+            ],
+        ];
+    }
+
+    private function parseRequest(string $req, array $queryParams = []): Request
     {
         $lines = explode("\r\n", $req);
         [$method, $path] = explode(' ', array_shift($lines));
@@ -156,6 +207,12 @@ class SignerV4Test extends TestCase
 
         $req = new Request($method, '/', [], $headers, StringStream::create(implode("\n", $lines)));
         $req->setEndpoint('https://' . $headers['Host'] . $path);
+
+        // currently the library cannot properly parse query params if they contain arrays, so we need to set them manually
+        foreach ($queryParams as $k => $v) {
+            $req->setQueryAttribute($k, $v);
+        }
+
         // Ensure that the memoized property is filled, so that comparison works consistently.
         $req->getEndpoint();
 
