laravel-aws-worker icon indicating copy to clipboard operation
laravel-aws-worker copied to clipboard

UTF-8 characters unserialize() error at offset

Open faculezcano opened this issue 4 years ago • 17 comments
trafficstars

Hi! First of all, thanks for such a useful package.

Im having troubles with data unserialization from SQS. Looking arround a bit i found this forum post so i think it could be related to UTF-8 characters encoding to 1 character (possibly a ?) and php expecting 2 characters. At the end of the forum post says that setting the charset in the request headers utf characters will encode correctly. If that isnt possible the other approach could be base64 encode the data sent to sqs and decode it back.

Part of a stack trace:

{
   "class":"ErrorException",
   "message":"unserialize(): Error at offset 1000 of 2395 bytes",
   "code":0,
   "file":"/var/app/current/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php:53",
   "trace":[
      "/var/app/current/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php:53",
      "/var/app/current/vendor/laravel/framework/src/Illuminate/Queue/Jobs/Job.php:98",
      "/var/app/current/vendor/dusterio/laravel-aws-worker/src/Jobs/AwsJob.php:46",
      "/var/app/current/vendor/laravel/framework/src/Illuminate/Queue/Worker.php:356",
      "/var/app/current/vendor/dusterio/laravel-aws-worker/src/Wrappers/Laravel6Worker.php:37",
      "/var/app/current/vendor/dusterio/laravel-aws-worker/src/Controllers/WorkerController.php:135",
      "/var/app/current/vendor/dusterio/laravel-aws-worker/src/Controllers/LaravelController.php:45",
      "/var/app/current/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php:45",
      "/var/app/current/vendor/laravel/framework/src/Illuminate/Routing/Route.php:239",
      "/var/app/current/vendor/laravel/framework/src/Illuminate/Routing/Route.php:196",
      "/var/app/current/vendor/laravel/framework/src/Illuminate/Routing/Router.php:685",
      "/var/app/current/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:128",
      "/var/app/current/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:103",
      "/var/app/current/vendor/laravel/framework/src/Illuminate/Routing/Router.php:687",
      "/var/app/current/vendor/laravel/framework/src/Illuminate/Routing/Router.php:662",
      "/var/app/current/vendor/laravel/framework/src/Illuminate/Routing/Router.php:628",
      "/var/app/current/vendor/laravel/framework/src/Illuminate/Routing/Router.php:617"
   ]
}

faculezcano avatar Feb 26 '21 15:02 faculezcano

I've been having the same issue for months, and it's been difficult to debug and test +1

brad-tilmor avatar Mar 04 '21 19:03 brad-tilmor

We are running into unserialization issues also, for us it seems to be based around two spaces in a row. We haven't been able to figure out how or why this is happening. There are no special characters or anything, if we remove one of the spaces in the sqs message it works fine so two spaces is somehow an issue.

cbcoolbox avatar Mar 15 '21 15:03 cbcoolbox

Just upgraded to Laravel 8 and getting this issue. Any idea to find out which ones are an issue?

MPJHorner avatar Mar 19 '21 12:03 MPJHorner

We are running into unserialization issues also, for us it seems to be based around two spaces in a row. We haven't been able to figure out how or why this is happening. There are no special characters or anything, if we remove one of the spaces in the sqs message it works fine so two spaces is somehow an issue.

What do you mean "remove one of the sapces in the SQS message" ?

MPJHorner avatar Mar 19 '21 12:03 MPJHorner

@dusterio Do you have any idea what the cause of this might be (or have you run into it yourself)?

Update on my end, I ended up implementing a base64_encode workaround, and that seemed to solve it for a while, but after more requests were processed, I started seeing the error come up again, albeit less frequently.

brad-tilmor avatar Mar 22 '21 12:03 brad-tilmor

We are using beanstalk and we were able to talk to an AWS tech and they said they were able to reproduce this issue on their side. It apparently is some sort of bug with the daemon they have that reads from the sqs queue and shoves it into where the laravel worker can read it. We weren't giving a timeline on a fix or if they will even fix it but that's what we found out.

cbcoolbox avatar Mar 22 '21 13:03 cbcoolbox

@cbcoolbox Any updates?

Nilanth avatar Apr 02 '21 08:04 Nilanth

I can also confirm the behavior specified by @cbcoolbox with the double spaces, I was able to mitigate it in some cases by sanitizing any string that goes in the job with preg_replace('/\s+/', ' ', $yourString); and that lowered the amount of instances where this error was thrown, but this is not ideal/possible in all cases.

JulioPablo avatar Apr 04 '21 04:04 JulioPablo

@Nilanth No updates at all. We are now moving to docker and ECS to use SQS more directly to go around their daemon that's breaking everything. We have some silly hacky fixes similar to what @JulioPablo did for the time being. technically the base64 encoding of your message would be the best "fix" we had that work also but feels terrible to code this way. best of luck!

cbcoolbox avatar Apr 05 '21 21:04 cbcoolbox

Since upgrading elastic beanstalk to Amazon Linux 2 we've come across the same issue. In the end, I've found the problem is in the ruby aws SDK XML parser, it's configured to strip whitespace. /opt/elasticbeanstalk/lib/ruby/lib/ruby/gems/2.6.0/gems/aws-sdk-core-2.11.546/lib/aws-sdk-core/xml/parser/engines/ox.rb

The solution for me was to create a prebuild hook to patch the ruby file.

#!/bin/bash -eu

if [ -f "/.aws-sdk-core-xml-parser-engines-ox-fix-installed" ]; then
    exit 0
fi

sudo yum install -y patch
patch -u /opt/elasticbeanstalk/lib/ruby/lib/ruby/gems/2.6.0/gems/aws-sdk-core-2.11.546/lib/aws-sdk-core/xml/parser/engines/ox.rb -i .platform/files/aws-sdk-core-xml-parser-engines-ox.patch
touch /.aws-sdk-core-xml-parser-engines-ox-fix-installed
systemctl restart sqsd
--- ox.rb       2021-04-09 20:20:20.862069509 +0000
+++ ox-new.rb   2021-04-09 20:21:05.181225573 +0000
@@ -14,7 +14,7 @@
           Ox.sax_parse(
             @stack, StringIO.new(xml),
             :convert_special => true,
-            :skip => :skip_white
+            :skip => :skip_none
           )
         end

jdempster avatar Apr 12 '21 11:04 jdempster

To piggyback on @jdempster 's answer, I had permission issues using a prebuild hook, so I decided to put it all in an an ebextension file called .ebextensions/fix-xml-parsing.config, if that's helpful to anyone. Not sure yet if this will actually solve the problem, as I can't reliably replicate the error, but I'm hopeful! I'll post an update once enough time has passed that I can be confident it's solved.

UPDATE: This appears to have worked, we haven't run into any new unserialize() errors in the past 2 days. Thanks to @jdempster for this solution!

packages:
  yum:
    patch: []

commands:
  01_apply_patch:
    command: "/tmp/fix-xml-parsing.sh"

files:
  "/tmp/aws-sdk-core-xml-parser-engines-ox.patch":
      mode: "000755"
      content: |
        --- ox.rb       2021-04-09 20:20:20.862069509 +0000
        +++ ox-new.rb   2021-04-09 20:21:05.181225573 +0000
        @@ -14,7 +14,7 @@
                  Ox.sax_parse(
                    @stack, StringIO.new(xml),
                    :convert_special => true,
        -            :skip => :skip_white
        +            :skip => :skip_none
                  )
                end
  "/tmp/fix-xml-parsing.sh":
      mode: "000755"
      content : |
        #!/bin/bash

        if [ -f "/.aws-sdk-core-xml-parser-engines-ox-fix-installed" ]; then
            exit 0
        fi

        if systemctl list-units --full -all | grep -Fq "sqsd.service"; then
            /usr/bin/patch --ignore-whitespace -u /opt/elasticbeanstalk/lib/ruby/lib/ruby/gems/2.6.0/gems/aws-sdk-core-2.11.546/lib/aws-sdk-core/xml/parser/engines/ox.rb -i /tmp/aws-sdk-core-xml-parser-engines-ox.patch
            touch /.aws-sdk-core-xml-parser-engines-ox-fix-installed
            systemctl restart sqsd
            echo "Installed xml parsing patch!"
            exit 0
        fi

        exit 0

brad-tilmor avatar Apr 28 '21 19:04 brad-tilmor

The permission denied issue will most likely be missing the execute flag chmod +x before you zip up the files.

jdempster avatar May 01 '21 20:05 jdempster

@Nilanth No updates at all. We are now moving to docker and ECS to use SQS more directly to go around their daemon that's breaking everything. We have some silly hacky fixes similar to what @JulioPablo did for the time being. technically the base64 encoding of your message would be the best "fix" we had that work also but feels terrible to code this way. best of luck!

@cbcoolbox Which driver are you using for SQS in ECS?

Nilanth avatar May 17 '21 13:05 Nilanth

@Nilanth We have a separate container for jobs and laravel reads directly from SQS. Pretty sure it's just built into laravel (I don't use laravel we are helping other products on our team that do).

cbcoolbox avatar May 17 '21 14:05 cbcoolbox

@jdempster and @brad-tilmor this has worked a treat for us thank you so much for sharing!

davecalnan avatar Jun 04 '21 14:06 davecalnan

@jdempster and @brad-tilmor this worked for me too, Thanks for sharing.

Nilanth avatar Jun 04 '21 14:06 Nilanth

Looks like this issue has been fixed in the latest platform version of 3.3.4

pushpak avatar Aug 04 '21 17:08 pushpak

Marking as stale. If this issue persists as a problem, please open a new issue. Thanks!

fylzero avatar Jul 06 '23 07:07 fylzero