nocobase/nocobase · error

Failed to register OAuth client (formatOauthError with respo

Error message

Failed to register OAuth client (formatOauthError with response data and status)

What it means

Thrown by registerOauthClient when the dynamic client registration endpoint responded with a non-2xx status. The response body (parsed by parseJsonResponse) and HTTP status are formatted via formatOauthError, which prefers the RFC 7591 error / error_description fields, falling back to the raw body text or 'HTTP <status>'. This means the server actively rejected the registration request.

Source

Thrown at packages/core/cli/src/lib/env-auth.ts:434

      {
        operation: 'Registering OAuth client',
        onRetry: (message) => updateTask(message),
      },
    );
  } catch (error: any) {
    throw new Error(
      formatOauthFetchFailure('Failed to register OAuth client.', {
        envName: options.envName,
        baseUrl: options.baseUrl,
        url: metadata.registration_endpoint,
        rawMessage: error?.message,
      }),
    );
  }
  const data = await parseJsonResponse(response);

  if (!response.ok) {
    throw new Error(formatOauthError('Failed to register OAuth client', data, response.status));
  }

  if (!data || typeof data !== 'object' || typeof data.client_id !== 'string') {
    throw new Error('OAuth client registration succeeded but no client_id was returned.');
  }

  return {
    clientId: data.client_id as string,
  };
}

function encodeBase64Url(input: Buffer) {
  return input
    .toString('base64')
    .replace(/\+/g, '-')
    .replace(/\//g, '_')
    .replace(/=+$/g, '');
}

View on GitHub (pinned to fa42722fef)

Solutions

  1. Read the error/error_description appended to the message and fix the reported metadata issue (e.g. invalid redirect_uri or scope).
  2. Confirm the OAuth server permits dynamic client registration (RFC 7591); if it requires an initial access token, register the client manually and configure the client_id instead.
  3. Check the server/proxy logs for the 4xx/5xx status shown after 'HTTP' in the message to identify infrastructure issues.
  4. Re-run `nb env auth <env>` after correcting server configuration or upgrading the server.

Example fix

// server-side: enable dynamic registration or provide static credentials
// before
// registration_endpoint returns 403 { "error": "access_denied" }
// after (server config)
// oauth: { allowDynamicRegistration: true }  // or pre-registered client_id used instead
Defensive patterns

Strategy: try-catch

Validate before calling

// check the server advertises dynamic registration before attempting it
const meta = await (await fetch(`${base}/.well-known/oauth-authorization-server`)).json();
if (!meta.registration_endpoint) {
  throw new Error('Server does not support dynamic client registration; configure a client_id manually.');
}

Try / catch

try {
  await registerOauthClient(options);
} catch (err) {
  const msg = String(err.message);
  if (/HTTP (401|403)/.test(msg)) {
    console.error('Dynamic registration rejected: register the client manually or enable it server-side.');
  } else throw err;
}

Prevention

When it happens

Trigger: POST to registration_endpoint returning 4xx/5xx, e.g. 401 unauthorized (registration requires an initial access token), 400 invalid_client_metadata (malformed redirect URIs or scope), 403 forbidden (registration disabled on the server), or 502 from a reverse proxy.

Common situations: OAuth server has dynamic client registration disabled; server requires an initial access token the CLI does not send; reverse proxy (nginx) returning 404/502 because the endpoint path is rewritten; server version changed its registration API; scope/redirect_uri values rejected by server policy.

Related errors


AI-assisted analysis of nocobase/nocobase@fa42722fef (2026-09-01). Data as JSON: /api/errors/9fa04cc7afb3f4f8. Report an issue: GitHub.