louislam/uptime-kuma · error · Error

The oauth config is invalid. ${e.message}

Error message

The oauth config is invalid. ${e.message}

What it means

During a poll of an HTTP/keyword/json-query monitor configured with auth_method === 'oauth2-cc', the monitor tries to obtain an OAuth2 access token via makeOidcTokenClientCredentialsRequest() (cached on this.oauthAccessToken). Any failure there — network error, non-2xx from the token endpoint, malformed token response, bad client credentials — is caught and re-thrown wrapped as 'The oauth config is invalid. <original message>'. This unified message surfaces as the monitor's bean.msg, so it is what you see in the UI.

Source

Thrown at server/model/monitor.js:509

                    }

                    // OIDC: Basic client credential flow.
                    // Additional grants might be implemented in the future
                    let oauth2AuthHeader = {};
                    if (this.auth_method === "oauth2-cc") {
                        try {
                            if (
                                this.oauthAccessToken === undefined ||
                                new Date(this.oauthAccessToken.expires_at * 1000) <= new Date()
                            ) {
                                this.oauthAccessToken = await this.makeOidcTokenClientCredentialsRequest();
                            }
                            oauth2AuthHeader = {
                                Authorization:
                                    this.oauthAccessToken.token_type + " " + this.oauthAccessToken.access_token,
                            };
                        } catch (e) {
                            throw new Error("The oauth config is invalid. " + e.message);
                        }
                    }

                    let agentFamily = undefined;
                    if (this.ipFamily === "ipv4") {
                        agentFamily = 4;
                    }
                    if (this.ipFamily === "ipv6") {
                        agentFamily = 6;
                    }

                    const httpsAgentOptions = {
                        maxCachedSessions: 0, // Use Custom agent to disable session reuse (https://github.com/nodejs/node/issues/3940)
                        rejectUnauthorized: !this.getIgnoreTls(),
                        secureOptions: crypto.constants.SSL_OP_LEGACY_SERVER_CONNECT,
                        autoSelectFamily: true,
                        ...(agentFamily ? { family: agentFamily } : {}),
                    };

View on GitHub (pinned to 6b5ea01557)

Solutions

  1. Replay the token request with curl using the same client_id/secret and token_url to see the real error body: `curl -X POST <token_url> -u '<client_id>:<client_secret>' -d 'grant_type=client_credentials' -d 'scope=<scope>'`.
  2. Verify the token URL, client_id, client_secret and scope fields on the monitor match what your IdP issued.
  3. If the IdP uses a self-signed or internal CA, configure Uptime Kuma to trust it (the httpsAgentOptions uses rejectUnauthorized = !ignoreTls, so toggle 'Ignore TLS Error' on the monitor if appropriate).
  4. Check network egress from the Uptime Kuma host to the IdP (DNS, proxy, firewall).
  5. Inspect the underlying message appended after 'The oauth config is invalid.' — it carries the IdP's actual response (e.g. 'invalid_client').

Example fix

// before
catch (e) {
    throw new Error("The oauth config is invalid. " + e.message);
}

// after — preserve the wrapped error's status/code so the UI can react
} catch (e) {
    const err = new Error("The oauth config is invalid. " + e.message);
    err.cause = e;
    err.status = e.response?.status;
    throw err;
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate the oauth2-cc config and probe the token endpoint before relying on it
async function probeOauth2CC({ tokenUrl, clientId, clientSecret, scope }) {
    const body = new URLSearchParams({ grant_type: "client_credentials" });
    if (scope) body.set("scope", scope);
    const res = await fetch(tokenUrl, {
        method: "POST",
        headers: { Authorization: "Basic " + Buffer.from(`${clientId}:${clientSecret}`).toString("base64"), "Content-Type": "application/x-www-form-urlencoded" },
        body
    });
    if (!res.ok) throw new Error(`IdP responded ${res.status}: ${await res.text()}`);
    const json = await res.json();
    if (!json.access_token) throw new Error("IdP returned no access_token");
    return json;
}

Type guard

function isOauthConfigComplete(cfg) {
    return Boolean(cfg && cfg.auth_method === "oauth2-cc" && cfg.oauth_token_url && cfg.oauth_client_id && cfg.oauth_client_secret);
}

Try / catch

// Surface the wrapped IdP error to operators
try {
    oauth2AuthHeader = /* ...makeOidcTokenClientCredentialsRequest() path... */;
} catch (e) {
    if (/oauth config is invalid/i.test(e.message)) {
        bean.msg = e.message;        // shown in the monitor UI
        bean.status = DOWN;
        // optionally e.cause / e.status for richer handling
    }
}

Prevention

When it happens

Trigger: oauth2-cc monitor with a wrong token URL, wrong client_id/client_secret, a token endpoint that returns an error JSON (e.g. invalid_grant), an issuer that requires a scope you did not configure, a self-signed cert on the token endpoint blocked by rejectUnauthorized, or the IdP being unreachable from the Uptime Kuma host.

Common situations: Typo in the OIDC token URL; rotated client secret not updated in Uptime Kuma; IdP rate-limiting or returning 401; clock skew breaking token refresh; corporate proxy intercepting TLS to the IdP.

Related errors


AI-assisted analysis of louislam/uptime-kuma@6b5ea01557 (2026-08-12). Data as JSON: /api/errors/0c4c90d6abe2d4f7. Report an issue: GitHub.