thephpleague/oauth2-server · critical · OAuthServerException

server_error

server_error

Error message

An unexpected error has occurred

What it means

A generic 500-level server_error wrapped as OAuthServerException::serverError('An unexpected error has occurred', $e). In DeviceCodeGrant::generateUserCode it catches TypeError or Error from random_int() / string generation and rethrows as this opaque server error. It indicates an unexpected engine-level failure while building the user code, not a client mistake.

Solutions

  1. Check the PHP error log for the wrapped previous exception ($e) to find the real cause
  2. Verify setUserDataCharacterSet (or equivalent) was given a valid non-empty string of single-byte characters
  3. Ensure the runtime provides a working CSPRNG (php -r "var_dump(function_exists('random_int'));" and /dev/urandom availability)
  4. Upgrade the library and PHP to supported versions

Example fix

// before
$grant->setUserDataCharacterSet('ÁÉÍÓÚÀÈÌÒÙÄËÏÖÜ'); // multibyte chars can break byte-based generation
// after
$grant->setUserDataCharacterSet(DeviceCodeGrant::DEFAULT_USER_CODE_CHARACTERS); // BCDFGHJKLMNPQRSTVWXZ
Defensive patterns

Strategy: try-catch

Validate before calling

if (!function_exists('random_int') || !is_string($userCodeCharacters)) {
    throw new \RuntimeException('CSPRNG unavailable or invalid user code character set');
}

Type guard

function isValidUserCharacterSet(?string $chars): bool {
    return $chars !== null && $chars !== '' && strlen($chars) === mb_strlen($chars);
}

Try / catch

try {
    $grant->issueDeviceCode($client, $user, $scopes, $interval, $verifyUri);
} catch (OAuthServerException $e) {
    if ($e->getErrorType() === 'server_error') {
        error_log('Device code generation failed: ' . $e->getPrevious());
    }
    throw $e;
}

Prevention

When it happens

Trigger: issueDeviceCode -> generateUserCode when random_int(0, 19) or the surrounding user-code loop throws TypeError or Error - e.g. invalid charset string passed as the user code alphabet, or a PHP engine/CSPRNG fault.

Common situations: Custom user code character set configured incorrectly (e.g. non-string multibyte value); PHP without a working random source in a hardened container; running an unsupported PHP version where random_int is unavailable.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of thephpleague/oauth2-server@9d2f6fc0a0 (2026-09-15). Data as JSON: /api/errors/bd2227c26fffebdf. Report an issue: GitHub.

Appendix: source

Thrown at src/Grant/DeviceCodeGrant.php:312

    /**
     * Generate a new user code.
     *
     * @throws OAuthServerException
     */
    protected function generateUserCode(int $length = 8): string
    {
        try {
            $userCode = '';
            $userCodeCharacters = 'BCDFGHJKLMNPQRSTVWXZ';

            while (strlen($userCode) < $length) {
                $userCode .= $userCodeCharacters[random_int(0, 19)];
            }

            return $userCode;
            // @codeCoverageIgnoreStart
        } catch (TypeError | Error $e) {
            throw OAuthServerException::serverError('An unexpected error has occurred', $e);
        } catch (Exception $e) {
            // If you get this message, the CSPRNG failed hard.
            throw OAuthServerException::serverError('Could not generate a random string', $e);
        }
        // @codeCoverageIgnoreEnd
    }

    public function setIntervalVisibility(bool $intervalVisibility): void
    {
        $this->intervalVisibility = $intervalVisibility;
    }

    public function getIntervalVisibility(): bool
    {
        return $this->intervalVisibility;
    }

    public function setIncludeVerificationUriComplete(bool $includeVerificationUriComplete): void

View on GitHub (pinned to 9d2f6fc0a0)