laravel/framework · error · DecryptException

The payload is invalid.

Error message

The payload is invalid.

What it means

Encrypter::getJsonPayload first checks is_string($payload). If the caller passed a non-string (array, object, null) to Encrypter::decrypt(), it throws DecryptException('The payload is invalid.') before any base64/JSON parsing. This guards the downstream json_decode from type errors.

Solutions

  1. Coerce/null-check the input before calling decrypt: $c = Request::cookie('foo'); return $c ? Crypt::decrypt($c) : null;
  2. Make sure the value passed is the raw base64 ciphertext string exactly as produced by encrypt().
  3. If you stored the decoded payload, re-encode it before decrypting or store the original ciphertext instead.

Example fix

// before
$value = Crypt::decrypt(Request::cookie('session_payload'));

// after
$raw = Request::cookie('session_payload');
$value = is_string($raw) ? Crypt::decrypt($raw) : null;
Defensive patterns

Strategy: type-guard

Validate before calling

if (! is_string($payload) || $payload === '') {
    return null; // or throw a domain-specific exception
}
return Crypt::decrypt($payload);

Type guard

function isDecryptableString(mixed $payload): bool {
    return is_string($payload) && $payload !== '';
}

Prevention

When it happens

Trigger: Calling Crypt::decrypt($nonString) where $nonString is null, an array (e.g. already-decoded payload), an object, or an integer; reading a missing cookie/config key that returns null and passing it straight to decrypt().

Common situations: decrypting Request::cookie('foo') when the cookie is absent (null); passing the result of json_decode twice; chaining decrypt onto a function that returns array|null; test fixtures that pass arrays directly.

Related errors


AI-assisted analysis of laravel/framework@e0f6eb3518 (2026-08-11). Data as JSON: /api/errors/b1c2d17061b10bac. Report an issue: GitHub.

Appendix: source

Thrown at src/Illuminate/Encryption/Encrypter.php:244

     * @return string
     */
    protected function hash(#[\SensitiveParameter] $iv, #[\SensitiveParameter] $value, #[\SensitiveParameter] $key)
    {
        return hash_hmac('sha256', $iv.$value, $key);
    }

    /**
     * Get the JSON array from the given payload.
     *
     * @param  string  $payload
     * @return array
     *
     * @throws \Illuminate\Contracts\Encryption\DecryptException
     */
    protected function getJsonPayload($payload)
    {
        if (! is_string($payload)) {
            throw new DecryptException('The payload is invalid.');
        }

        $payload = json_decode(base64_decode($payload), true);

        // If the payload is not valid JSON or does not have the proper keys set we will
        // assume it is invalid and bail out of the routine since we will not be able
        // to decrypt the given value. We'll also check the MAC for this encryption.
        if (! $this->validPayload($payload)) {
            throw new DecryptException('The payload is invalid.');
        }

        return $payload;
    }

    /**
     * Verify that the encryption payload is valid.
     *
     * @param  mixed  $payload

View on GitHub (pinned to e0f6eb3518)