Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

perpetualErrosion's avatar

Laravel Reverb throws Pusher "Data decoding error"

I'm having trouble setting up Laravel Reverb on my live server. It works fine on localhost, however, I get a data decoding error whenever I try to broadcast an event on my live server.

This is the configuration from my .env:

BROADCAST_CONNECTION=reverb

REVERB_APP_ID=app_123
REVERB_APP_KEY=key_123
REVERB_APP_SECRET=secret_123
REVERB_HOST="ws.{domain_name}app"
REVERB_SCHEME=https
REVERB_SERVER_PORT=8080
REVERB_PORT=443

This is my Caddyfile:

{domain_name}.app, www.{domain_name}.app {
	# Set this path to your site's directory.
	root * /home/digitalocean/{domain_name}.app/current/public

	# Provide Zstd and Gzip compression
	encode zstd gzip

	# Enable the static file server.
	file_server

	# Another common task is to set up a reverse proxy:
	# reverse_proxy localhost:8080

	# Or serve a PHP site through php-fpm:
	php_fastcgi unix//run/php/php8.3-fpm.sock
}

ws.{domain_name}.app {
	@websockets {
		header Connection *Upgrade*
		header Upgrade websocket
	}
	reverse_proxy @websockets localhost:8080

	encode zstd gzip
}

client.{domain_name}.app {
	reverse_proxy 0.0.0.0:3000
	encode gzip
}

customer.{domain_name}.app {
	reverse_proxy 0.0.0.0:4000
	encode gzip
}

NOTE: The error is thrown on Line 798 of /vendor/pusher/pusher-php-server/src/Pusher.php. I'm using php-pusher-server version7.2.4.

Edit #1:

The exception is triggered by the following line (i.e., line 798 in Pusher.php):

$response_body = json_decode($response->getBody(), false, 512, JSON_THROW_ON_ERROR);

I added a dd($response->getBody()) to both my server and the local machine (where reverb works btw) and I got the following responses.

From server:

GuzzleHttp\Psr7\Stream {#2161 // vendor/pusher/pusher-php-server/src/Pusher.php:794
  -stream: stream resource @1264
    wrapper_type: "PHP"
    stream_type: "TEMP"
    mode: "w+b"
    unread_bytes: 0
    seekable: true
    uri: "php://temp"
    options: []
  }
  -size: null
  -seekable: true
  -readable: true
  -writable: true
  -uri: "php://temp"
  -customMetadata: []
}

On local machine:

GuzzleHttp\Psr7\Stream {#2821 // vendor/pusher/pusher-php-server/src/Pusher.php:794
  -stream: stream resource @52
    wrapper_type: "PHP"
    stream_type: "TEMP"
    mode: "w+b"
    unread_bytes: 0
    seekable: true
    uri: "php://temp"
    options: []
  }
  -size: null
  -seekable: true
  -readable: true
  -writable: true
  -uri: "php://temp"
  -customMetadata: []
}

The two responses seem to be the same; however, when I cast the two values as a string like so, I get.

From server:

"" // vendor/pusher/pusher-php-server/src/Pusher.php:794

On local machine:

"{}" // vendor/pusher/pusher-php-server/src/Pusher.php:794
0 likes
2 replies
LaryAI's avatar
Level 58

The "Data decoding error" you're encountering with Laravel Reverb and Pusher typically indicates an issue with the data being sent or received, or a misconfiguration in your setup. Here are a few steps to troubleshoot and resolve this issue:

  1. Check Your Environment Configuration: Ensure that your .env file is correctly configured and that there are no typos or incorrect values. Specifically, verify that the REVERB_HOST is correctly set to your domain.

    BROADCAST_CONNECTION=reverb
    
    REVERB_APP_ID=app_123
    REVERB_APP_KEY=key_123
    REVERB_APP_SECRET=secret_123
    REVERB_HOST="ws.{domain_name}.app"
    REVERB_SCHEME=https
    REVERB_SERVER_PORT=8080
    REVERB_PORT=443
    
  2. Caddyfile Configuration: Ensure that your Caddyfile is correctly set up to handle WebSocket connections. Your configuration looks mostly correct, but double-check the reverse_proxy settings and ensure that the WebSocket headers are properly handled.

    {domain_name}.app, www.{domain_name}.app {
        root * /home/digitalocean/{domain_name}.app/current/public
        encode zstd gzip
        file_server
        php_fastcgi unix//run/php/php8.3-fpm.sock
    }
    
    ws.{domain_name}.app {
        @websockets {
            header Connection *Upgrade*
            header Upgrade websocket
        }
        reverse_proxy @websockets localhost:8080
        encode zstd gzip
    }
    
    client.{domain_name}.app {
        reverse_proxy 0.0.0.0:3000
        encode gzip
    }
    
    customer.{domain_name}.app {
        reverse_proxy 0.0.0.0:4000
        encode gzip
    }
    
  3. Check SSL/TLS Configuration: Ensure that your SSL/TLS certificates are correctly set up and that there are no issues with HTTPS connections. Misconfigured SSL can sometimes cause data decoding errors.

  4. Verify Reverb Server: Ensure that the Reverb server is running and accessible on the specified port (8080). You can test this by trying to connect to the WebSocket server directly using a tool like wscat:

    wscat -c ws://ws.{domain_name}.app:8080
    
  5. Check for Errors in Logs: Check the logs for both your Laravel application and the Reverb server for any errors or warnings that might provide more insight into the issue.

  6. Update Dependencies: Ensure that all your dependencies are up to date. Sometimes, bugs in older versions of libraries can cause unexpected issues.

    composer update
    npm update
    
  7. Test with a Simple Event: Try broadcasting a simple event to see if the issue persists. This can help isolate whether the problem is with the data being sent or with the configuration.

    // In your Laravel application
    event(new \App\Events\SimpleEvent('Test message'));
    
    // SimpleEvent.php
    namespace App\Events;
    
    use Illuminate\Broadcasting\Channel;
    use Illuminate\Broadcasting\InteractsWithSockets;
    use Illuminate\Broadcasting\PresenceChannel;
    use Illuminate\Broadcasting\PrivateChannel;
    use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
    use Illuminate\Foundation\Events\Dispatchable;
    use Illuminate\Queue\SerializesModels;
    
    class SimpleEvent implements ShouldBroadcast
    {
        use Dispatchable, InteractsWithSockets, SerializesModels;
    
        public $message;
    
        public function __construct($message)
        {
            $this->message = $message;
        }
    
        public function broadcastOn()
        {
            return new Channel('test-channel');
        }
    
        public function broadcastAs()
        {
            return 'simple-event';
        }
    }
    

By following these steps, you should be able to identify and resolve the "Data decoding error" you're encountering with Laravel Reverb and Pusher. If the issue persists, consider providing more detailed logs or error messages to further diagnose the problem.

perpetualErrosion's avatar
Level 2

Update

I managed to fix the issue. It seems like it was throwing a JSON error because my websockets were misconfigured. I wasn't able to resolve the issue whilst still using my ws subdomain. However, the following Caddyfile configuration works.

Caddyfile:

{domain_name}.app, www.{domain_name}.app {
        # Set this path to your site's directory.
        root * /home/digitalocean/{domain_name}.app/current/public

        # Provide Zstd and Gzip compression
        encode zstd gzip

        # Enable the static file server.
        file_server

        @websockets {
            header Connection *Upgrade*
            header Upgrade    websocket
        }

        reverse_proxy @websockets 0.0.0.0:8080

        # Or serve a PHP site through php-fpm:
        php_fastcgi unix//run/php/php8.3-fpm.sock
}

client.{domain_name}.app {
        reverse_proxy 0.0.0.0:3000
        encode gzip
}

customer.{domain_name}.app {
        reverse_proxy 0.0.0.0:4000
        encode gzip
}

The relevant environment variables for my Laravel application:

.env (Laravel)

BROADCAST_CONNECTION=reverb

REVERB_APP_ID={app_id}
REVERB_APP_KEY={app_key}
REVERB_APP_SECRET={app_secret}
REVERB_HOST="127.0.0.1"
REVERB_SCHEME=http
REVERB_SERVER_PORT=8080
REVERB_PORT=8080

The relevant environment variables for my NextJS (frontend) application:

.env.local (NextJS)

NEXT_PUBLIC_BASE_URL=https://{domain_name}.app/api
NEXT_PUBLIC_REVERB_APP_KEY={app_key}
NEXT_PUBLIC_REVERB_HOST={domain_name}.app
NEXT_PUBLIC_REVERB_PORT=443
NEXT_PUBLIC_REVERB_SCHEME="https"

Please or to participate in this conversation.