---
title: "Exceptions — Crypto for Laravel | Roundly"
description: "Every failure is a typed subtype of CryptoException — catch broadly or precisely, and re-wrap at your own boundary."
url: https://roundly-consulting.com/open-source/docs/crypto-for-laravel/exceptions
language: en
---

[All packages](https://roundly-consulting.com/open-source.md)

[Crypto for Laravel](https://roundly-consulting.com/open-source/docs/crypto-for-laravel.md)

# Exceptions

Everything the package throws extends RoundlyConsulting\\Crypto\\Exceptions\\CryptoException, an abstract RuntimeException. Catch it broadly, or a subtype to react precisely — a common pattern is to re-wrap it as your own domain exception:

```php
use RoundlyConsulting\Crypto\Exceptions\CryptoException;
use RoundlyConsulting\Crypto\Signature\Algorithm;

try {
    $claims = $jws->verify($token, $verifier, Algorithm::RS256);
} catch (CryptoException $e) {
    // any crypto failure — malformed token, algorithm mismatch, bad signature, weak key, …
    throw new TokenRejected(previous: $e);   // your own domain exception
}
```

## Hierarchy

```
RuntimeException
└── CryptoException (abstract)
    ├── Codec\InvalidEncodingException
    ├── Aead\DecryptionFailedException
    ├── Aead\InvalidAeadParameterException
    ├── Random\InvalidLengthException
    ├── Hash\InvalidHkdfParameterException
    ├── Signature\AlgorithmMismatchException
    ├── Signature\InvalidSignatureException
    ├── Signature\KeyLoadException
    ├── Signature\WeakKeyException
    ├── Jose\MalformedTokenException
    ├── Jose\MalformedJwkException
    ├── Jose\ClaimMismatchException
    │   ├── Jose\TokenExpiredException
    │   └── Jose\TokenNotYetValidException
    ├── X509\MalformedCertificateException
    ├── X509\InvalidChainException
    ├── X509\InvalidLeewayException
    ├── Asn1\MalformedDerException
    ├── Cose\MalformedCborException
    ├── Cose\UnsupportedAlgorithmException
    └── Otp\InvalidOtpParameterException
```

## When each is thrown

| Exception | Thrown when |
| --- | --- |
| `Codec\InvalidEncodingException` | A base64url, base64, base32 or hex string is invalid or non-canonical. |
| `Aead\DecryptionFailedException` | open() or decrypt() cannot authenticate the input — a wrong key, nonce or associated data, a changed ciphertext or tag, or input too short to hold a tag. One fixed message for every cause. |
| `Aead\InvalidAeadParameterException` | An AES-256-GCM key is not 32 bytes or a nonce not 12 bytes — a programming error, never a property of the data — or OpenSSL refuses the cipher. |
| `Random\InvalidLengthException` | A requested random length is out of range, or an alphabet is empty or not valid UTF-8. |
| `Hash\InvalidHkdfParameterException` | HKDF was given empty input keying material, or a length outside 1–255 × the hash length — a programming error. |
| `Signature\AlgorithmMismatchException` | A key type does not match the algorithm, or a token’s alg does not match the pinned one. |
| `Signature\InvalidSignatureException` | A signature fails to verify, or ECDSA DER cannot be normalised. |
| `Signature\KeyLoadException` | OpenSSL cannot load, parse or generate a key, a key is the wrong type, an Ed25519 secret key’s public half does not match its seed, or a loader cannot find its file, disk or config value or cannot lock or write a generated key. |
| `Signature\WeakKeyException` | Key material is too weak or out of range — HMAC secret (or one shorter than the HS384 / HS512 hash size), RSA size or exponent, unsupported curve. |
| `Jose\MalformedTokenException` | A compact JWS is structurally invalid — segments, JSON, a header or payload that is not a JSON object, oversize, crit. |
| `Jose\MalformedJwkException` | A JWK is malformed, oversized, or carries private or unknown members. |
| `Jose\ClaimMismatchException` | A claim is absent or has the wrong type (base class of the two below). |
| `Jose\TokenExpiredException` | assertTemporal() finds that exp has passed. |
| `Jose\TokenNotYetValidException` | assertTemporal() finds nbf or iat in the future. |
| `X509\MalformedCertificateException` | A certificate cannot be read or parsed, is oversized, carries bytes after its DER, or has an unsupported key type. |
| `X509\InvalidChainException` | A chain is empty, longer than 10 certificates, not a list (a gap or a string key), holds an entry of the wrong type, or is indexed out of range. |
| `X509\InvalidLeewayException` | A validity predicate receives a negative leeway. |
| `Asn1\MalformedDerException` | DER input violates X.690’s canonical rules or the decoder’s caps. |
| `Cose\MalformedCborException` | CBOR or authenticator data is malformed or non-canonical, or a COSE key field has the wrong CBOR type. |
| `Cose\UnsupportedAlgorithmException` | An unknown COSE algorithm, key type or curve — or EdDSA without ext-sodium. |
| `Otp\InvalidOtpParameterException` | OTP digits, period or window are out of range, or a secret is empty, shorter than 10 bytes or all zero bytes. |

Catching ClaimMismatchException also catches both temporal failures. Es, Rs and EdDSA verification return false for a wrong-length or malformed signature rather than throwing; inside Jws::verify() a failed signature surfaces as InvalidSignatureException.

## Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

[More ways to support, including crypto](https://roundly-consulting.com/support-us.md)

By donating, you agree to our [donation terms](https://roundly-consulting.com/donation-terms.md).

[Support our open source work (opens in a new tab)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Join us on Patreon (opens in a new tab)](https://www.patreon.com/cw/roundly)

## Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.

[Get a quote in 48 hours](https://roundly-consulting.com/contact.md) [Browse all packages](https://roundly-consulting.com/open-source/docs/crypto-for-laravel.md)
