karatelabs/karate · error · OAuth2Exception
Token refresh failed: server returned invalid JSON response
Error message
Token refresh failed: server returned invalid JSON response
What it means
OAuth2TokenManager.refreshToken() expects the token endpoint to return a JSON body. If Json.of(body) cannot parse the HTTP response, the manager clears the cached token and throws OAuth2Exception with this message, because a non-JSON response cannot contain a valid token payload.
Solutions
- Verify the OAuth2 token endpoint URL returns JSON (curl it and inspect the body).
- Check HTTP status and response body on the failing request — log the raw body before parsing.
- Fix proxy/WAF interference or point to the correct issuer token endpoint.
- Handle OAuth2Exception by re-authenticating from scratch (credentials grant) rather than refresh.
-
Example fix
// before
var mgr = new OAuth2TokenManager(cfg.tokenUrlWrong);
// after
var mgr = new OAuth2TokenManager("https://idp.example.com/oauth2/token"); // returns application/json Defensive patterns
Strategy: try-catch
Validate before calling
// verify endpoint before configuring: curl -s $TOKEN_URL must return JSON
curl -s -o /dev/null -w '%{content_type}' $TOKEN_URL # expect application/json Try / catch
try { token = mgr.refresh(); } catch (OAuth2Exception e) { if (e.getMessage().contains('invalid JSON')) { log.error('Token endpoint returned non-JSON: check URL/proxy'); reauthenticate(); } else throw e; } Prevention
- Point tokenUrl at the RFC 6749 token endpoint returning application/json
- Check for proxy/WAF HTML interstitials in your environment
- Validate the endpoint with curl before wiring it into config
- Log the raw response body on failure to diagnose quickly
When it happens
Trigger: Token endpoint returns HTML (login/error page), empty body, proxy interstitial, or plain text instead of JSON during refresh.
Common situations: Wrong token URL configured; expired redirect to a login page; corporate proxy or WAF injecting HTML; server 5xx returning text/plain error page.
Understand the failure class
Background: "Invalid JSON response" and "Failed to parse response" errors: when an API answers 200 but the body isn't the JSON your library expected — this error's family across 28 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Token refresh failed: expected JSON object but received
- Token refresh failed:
- Authorization flow failed: " + e.getMessage()
- Missing 'authorizationUrl' in OAuth config
- Missing 'client_id' in OAuth config
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/b4b2495ad2ab6eb3.
Report an issue: GitHub.
Appendix: source
Thrown at karate-core/src/main/java/io/karatelabs/http/OAuth2TokenManager.java:87
HttpResponse response = builder.invoke("post");
String body = response.getBodyString();
int status = response.getStatus();
if (status < 200 || status >= 300) {
String errorMessage = parseOAuthError(body, status);
logger.error("Token refresh failed: {}", errorMessage);
currentToken = null;
throw new OAuth2Exception(errorMessage);
}
Json json;
try {
json = Json.of(body);
} catch (Exception e) {
String errorMessage = "Token refresh failed: server returned invalid JSON response";
logger.error(errorMessage);
currentToken = null;
throw new OAuth2Exception(errorMessage);
}
if (!json.isObject()) {
String errorMessage = "Token refresh failed: expected JSON object but received " +
(json.isArray() ? "array" : "primitive value");
logger.error(errorMessage);
currentToken = null;
throw new OAuth2Exception(errorMessage);
}
Map<String, Object> data = json.asMap();
OAuth2Token newToken = OAuth2Token.fromMap(data);
storeToken(newToken);
logger.debug("Token refreshed successfully");
return newToken;
} catch (OAuth2Exception e) {
throw e;
} catch (Exception e) {View on GitHub (pinned to a22eb90246)