BookStackApp/BookStack · error · InvalidArgumentException

Issuer value must start with https://

Error message

Issuer value must start with https://

What it means

validateInitial() requires the OIDC issuer URL to use HTTPS, because the issuer is the trust root for discovery and token validation. A plain http:// (or otherwise malformed, e.g. missing scheme) issuer value is rejected immediately with an InvalidArgumentException.

Source

Thrown at app/Access/Oidc/OidcProviderSettings.php:64

        }
    }

    /**
     * Validate any core, required properties have been set.
     *
     * @throws InvalidArgumentException
     */
    protected function validateInitial(): void
    {
        $required = ['clientId', 'clientSecret', 'issuer'];
        foreach ($required as $prop) {
            if (empty($this->$prop)) {
                throw new InvalidArgumentException("Missing required configuration \"{$prop}\" value");
            }
        }

        if (!str_starts_with($this->issuer, 'https://')) {
            throw new InvalidArgumentException('Issuer value must start with https://');
        }
    }

    /**
     * Perform a full validation on these settings.
     *
     * @throws InvalidArgumentException
     */
    public function validate(): void
    {
        $this->validateInitial();

        $required = ['keys', 'tokenEndpoint', 'authorizationEndpoint'];
        foreach ($required as $prop) {
            if (empty($this->$prop)) {
                throw new InvalidArgumentException("Missing required configuration \"{$prop}\" value");
            }
        }

View on GitHub (pinned to 18f8469a1c)

Solutions

  1. Set OIDC_ISSUER to a full https:// URL exactly matching the IdP's advertised issuer (including realm/path).
  2. For local development, stand up the IdP behind HTTPS (e.g. reverse proxy with TLS, mkcert) instead of downgrading the check.
  3. Verify the exact issuer string against the IdP's .well-known/openid-configuration 'issuer' field — it must match character-for-character.
  4. Ensure no whitespace or quoting artifacts got into the env value; run php artisan config:clear afterwards.

Example fix

# before
OIDC_ISSUER=http://keycloak.local:8080/realms/main
# after
OIDC_ISSUER=https://keycloak.local/realms/main
Defensive patterns

Strategy: validation

Validate before calling

$issuer = config('oidc.issuer');
if (!is_string($issuer) || !str_starts_with($issuer, 'https://')) {
    throw new RuntimeException('OIDC issuer must be a full https:// URL');
}

Try / catch

try {
    $settings->validate();
} catch (InvalidArgumentException $e) {
    Log::error('OIDC issuer invalid: ' . $e->getMessage());
}
// or pre-check: assert(str_starts_with(config('oidc.issuer') ?? '', 'https://'));

Prevention

When it happens

Trigger: Setting oidc.issuer (OIDC_ISSUER) to an http:// URL, a bare hostname without scheme, a URL with a leading/trailing typo, or an empty-but-truthy value not starting with 'https://'.

Common situations: Local/dev IdPs served over plain HTTP (e.g. http://localhost:8080/realms/test) being pointed at in production config; copy-paste of issuer from docs losing the scheme; issuer behind an offloading proxy whose advertised URL is http.

Related errors


AI-assisted analysis of BookStackApp/BookStack@18f8469a1c (2026-09-02). Data as JSON: /api/errors/0749251b4f56932d. Report an issue: GitHub.