HeyPuter/puter · error · HttpError

internal_error

internal_error

Error message

Could not build authorization URL.

What it means

The OIDC start endpoint called `services.oidc.getAuthorizationUrl(provider, state, flow)` and it returned a falsy value, meaning the authorization URL could not be constructed. This is an internal server error — the provider is configured but the URL builder failed, likely due to missing provider metadata (issuer, authorization_endpoint) or a discovery failure.

Source

Thrown at src/backend/controllers/oidc/OIDCController.ts:381

                // Bind this flow to the initiating browser: a single-use
                // nonce lives both in the signed `state` and in an HttpOnly
                // companion cookie. The callback requires them to match, so a
                // `state` captured from an attacker's own flow can't be
                // replayed in a victim's browser (login-CSRF / session
                // fixation).
                const browserNonce = crypto
                    .randomBytes(32)
                    .toString('base64url');
                statePayload.nonce = browserNonce;

                const state = this.services.oidc.signState(statePayload);
                const url = await this.services.oidc.getAuthorizationUrl(
                    provider,
                    state,
                    flow,
                );
                if (!url)
                    throw new HttpError(
                        500,
                        'Could not build authorization URL.',
                        { legacyCode: 'internal_error' },
                    );

                res.cookie(OIDC_NONCE_COOKIE_NAME, browserNonce, {
                    // Same flags as the session cookie: SameSite=None;Secure
                    // on HTTPS so the cookie survives Apple's cross-site
                    // form_post callback; Lax on plain-HTTP self-host.
                    ...sessionCookieFlags(this.config),
                    httpOnly: true,
                    maxAge: OIDC_NONCE_EXPIRY_SEC * 1000,
                    path: '/',
                });
                res.redirect(302, url);
            },
        );

View on GitHub (pinned to 908ec23eda)

Solutions

  1. Verify the provider config includes a valid `issuer` URL pointing to the IdP's OIDC discovery endpoint.
  2. Check server-side network connectivity to the IdP — the discovery fetch may be timing out or blocked by a firewall.
  3. Confirm the IdP supports OIDC discovery (`.well-known/openid-configuration`).
  4. Check backend logs for the underlying error from `getAuthorizationUrl`.
Defensive patterns

Strategy: try-catch

Try / catch

try {
  window.location = `/auth/oidc/${provider}/start`;
} catch (e) {
  if (e.code === 'internal_error' && e.message.includes('authorization URL')) {
    console.error('OIDC provider misconfigured. Contact the administrator.');
  }
}

Prevention

When it happens

Trigger: Provider config exists (passed the 404 check) but is incomplete — missing authorization endpoint URL, malformed issuer, or the OIDC discovery document could not be fetched/parsed. The `getAuthorizationUrl` method returned null/undefined.

Common situations: Provider config has a client_id/secret but no issuer URL; the IdP's discovery endpoint is unreachable from the server; the discovery document is malformed; a provider config migration left fields blank.

Related errors


AI-assisted analysis of HeyPuter/puter@908ec23eda (2026-08-12). Data as JSON: /api/errors/53834b0237cbafa3. Report an issue: GitHub.