lcobucci/jwt · error · Lcobucci\JWT\Signer\InvalidKeyProvided

Key cannot be empty

Error message

Key cannot be empty

What it means

Thrown by InMemory::guardAgainstEmptyKey() when the key contents resolve to an empty string. InMemory deliberately refuses to construct keys from empty material, since an empty signing key is never valid.

Solutions

  1. Ensure the key source (env var, file, config) is populated with non-empty contents
  2. Check the mounted secret file is non-empty: `wc -c /run/secrets/jwt_key`
  3. Fail fast at boot: validate the key string before constructing InMemory
  4. Fix quoting/interpolation issues in .env or deployment manifests that drop the value

Example fix

// before
$key = InMemory::plainText($_ENV['JWT_SECRET'] ?? '');
// after
$secret = $_ENV['JWT_SECRET'] ?? '';
if ($secret === '') {
    throw new RuntimeException('JWT_SECRET is not set');
}
$key = InMemory::plainText($secret);
Defensive patterns

Strategy: validation

Validate before calling

if (!is_string($secret) || $secret === '') { throw new RuntimeException('JWT key is empty or not set'); }

Try / catch

try { $key = InMemory::plainText($secret); } catch (\Jose\Component\Signature\Exception\InvalidKeyProvided $e) { /* config error: empty key */ }

Prevention

When it happens

Trigger: InMemory::plainText(''), InMemory::base64Encoded(''), or InMemory::file() reading a zero-byte file; also an env var or config value that resolves to '' being passed to the key factory.

Common situations: Missing environment variable returning empty string, empty file mounted as a secret (e.g. K8s secret not populated), base64 of an empty string, config file with KEY= empty.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of lcobucci/jwt@375813049c (2026-09-14). Data as JSON: /api/errors/19f4c8d0a9d4ed16. Report an issue: GitHub.

Appendix: source

Thrown at src/Signer/Key/InMemory.php:85

            $file = new SplFileObject($path);
        } catch (Throwable $exception) {
            throw FileCouldNotBeRead::onPath($path, $exception);
        }

        $fileSize = $file->getSize();
        $contents = $fileSize > 0 ? $file->fread($file->getSize()) : '';
        assert(is_string($contents));

        self::guardAgainstEmptyKey($contents);

        return new self($contents, $passphrase);
    }

    /** @phpstan-assert non-empty-string $contents */
    private static function guardAgainstEmptyKey(string $contents): void
    {
        if ($contents === '') {
            throw InvalidKeyProvided::cannotBeEmpty();
        }
    }

    public function contents(): string
    {
        return $this->contents;
    }

    public function passphrase(): string
    {
        return $this->passphrase;
    }
}

View on GitHub (pinned to 375813049c)