karatelabs/karate · error · OAuth2Exception

Missing 'authorizationUrl' in OAuth config

Error message

Missing 'authorizationUrl' in OAuth config

What it means

buildAuthorizationUrl() requires an 'authorizationUrl' entry in the OAuth config map to construct the provider's authorize endpoint URL. If the key is absent, an OAuth2Exception is thrown immediately — the flow cannot start because there is nowhere to redirect the user for consent.

Solutions

  1. Add 'authorizationUrl' (the provider's /authorize endpoint) to the OAuth config map
  2. Check key spelling and casing exactly matches 'authorizationUrl'
  3. Validate all required keys (authorizationUrl, client_id, url) before invoking the flow

Example fix

// before
config = { "client_id": "abc", "url": "https://idp/token" }
// after
config = { "client_id": "abc", "url": "https://idp/token", "authorizationUrl": "https://idp/authorize" }
Defensive patterns

Strategy: validation

Validate before calling

// fail fast before calling authUrl()
Object authz = config.get("authorizationUrl");
if (authz == null || authz.toString().isBlank()) {
    throw new IllegalArgumentException("config.authorizationUrl is required");
}

Type guard

static String requireConfigKey(Map<String, Object> config, String key) {
    Object v = config.get(key);
    if (!(v instanceof String s) || s.isBlank()) {
        throw new IllegalArgumentException("Missing '" + key + "' in OAuth config");
    }
    return s;
}

Try / catch

try {
    String url = handler.authUrl(pkce, redirectUri);
} catch (OAuth2Exception e) {
    if (e.getMessage().contains("authorizationUrl")) {
        throw new ConfigurationException("Add authorizationUrl to OAuth config", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling authUrl() (via buildAuthorizationUrl) on a config map that lacks the 'authorizationUrl' key — e.g. a partially populated config, a typo like 'authorizationURL' or 'authUrl', or reusing a client-credentials config that only has a token endpoint.

Common situations: Config copied from a different OAuth flow that does not need an authorize endpoint, YAML/JSON key casing mistakes, or forgetting to set the key when assembling config programmatically.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12). Data as JSON: /api/errors/b9f506342d7116e7. Report an issue: GitHub.

Appendix: source

Thrown at karate-core/src/main/java/io/karatelabs/http/AuthorizationCodeAuthHandler.java:134

            return token;

        } catch (Exception e) {
            logger.error("Authorization flow failed: {}", e.getMessage());
            throw new OAuth2Exception("Authorization flow failed: " + e.getMessage(), e);
        } finally {
            if (callbackServer != null) {
                callbackServer.stop();
            }
        }
    }

    /**
     * Build authorization URL with all required parameters
     */
    private String buildAuthorizationUrl(PkceGenerator pkce, String redirectUri) {
        String authzEndpoint = (String) config.get("authorizationUrl");
        if (authzEndpoint == null) {
            throw new OAuth2Exception("Missing 'authorizationUrl' in OAuth config");
        }

        String clientId = (String) config.get("client_id");
        if (clientId == null) {
            throw new OAuth2Exception("Missing 'client_id' in OAuth config");
        }

        String scope = (String) config.getOrDefault("scope", "");

        StringBuilder url = new StringBuilder(authzEndpoint);
        url.append(authzEndpoint.contains("?") ? "&" : "?");
        url.append("response_type=code");
        url.append("&client_id=").append(urlEncode(clientId));
        url.append("&redirect_uri=").append(urlEncode(redirectUri));
        url.append("&code_challenge=").append(urlEncode(pkce.getChallenge()));
        url.append("&code_challenge_method=").append(pkce.getMethod());

        if (!scope.isEmpty()) {

View on GitHub (pinned to a22eb90246)