spring-projects/spring-security · error · RestClientException

Error running rest call

Error message

Error running rest call

What it means

KerberosRestTemplate overrides RestTemplate's doExecute to add SPNEGO/Kerberos authentication. Any non-RestClientException exception thrown during execution (I/O errors, GSS/Kerberos login problems, etc.) is wrapped in a RestClientException with the message 'Error running rest call' and the original cause attached, so callers get a single, uniform exception type.

Source

Thrown at kerberos/kerberos-client/src/main/java/org/springframework/security/kerberos/client/KerberosRestTemplate.java:255

		try {
			LoginContext lc = buildLoginContext();
			lc.login();
			Subject serviceSubject = lc.getSubject();
			return Subject.doAs(serviceSubject, new PrivilegedAction<T>() {

				@Override
				public T run() {
					return KerberosRestTemplate.this.doExecuteSubject(url, uriTemplate, method, requestCallback,
							responseExtractor);
				}
			});

		}
		catch (RestClientException ex) {
			throw ex;
		}
		catch (Exception ex) {
			throw new RestClientException("Error running rest call", ex);
		}
	}

	private <T> T doExecuteSubject(URI url, @Nullable String uriTemplate, @Nullable HttpMethod method,
			@Nullable RequestCallback requestCallback, @Nullable ResponseExtractor<T> responseExtractor)
			throws RestClientException {
		T result = super.doExecute(url, uriTemplate, method, requestCallback, responseExtractor);
		if (result == null) {
			throw new RestClientException("doExecute returned null");
		}
		return result;
	}

	private static final class ClientLoginConfig extends Configuration {

		private final @Nullable String keyTabLocation;

		private final @Nullable String userPrincipal;

View on GitHub (pinned to 96852e8860)

Solutions

  1. Inspect the cause via ex.getCause() to find the real Kerberos/IO failure and fix it.
  2. Verify the Kerberos setup: valid keytab, kinit'ed subject, correct service principal and JAAS config.
  3. Enable GSS/debug logging (sun.security.jgss.debug=true) to pinpoint the handshake stage that failed.

Example fix

// before
try { template.getForObject(url, String.class); } catch (RestClientException e) { log.error(e.getMessage()); }
// after
try { template.getForObject(url, String.class); }
catch (RestClientException e) {
    log.error("REST call failed", e.getCause()); // inspect real cause
    if (e.getCause() instanceof GSSException) { reestablishTicket(); }
}
Defensive patterns

Strategy: try-catch

Validate before calling

// preflight: ensure a fresh Kerberos ticket before calling
try (LoginContext lc = new LoginContext("KrbLogin")) { lc.login(); }

Try / catch

try {
    return template.getForObject(url, String.class);
} catch (RestClientException e) {
    Throwable cause = e.getCause();
    if (cause instanceof GSSException || cause instanceof IOException) {
        // re-authenticate / retry with backoff
    }
    throw e;
}

Prevention

When it happens

Trigger: Any request executed through KerberosRestTemplate (getForObject, exchange, etc.) where an underlying call throws a checked/unexpected Exception not already a RestClientException — e.g. GSSException during the Kerberos handshake or IOException from the connection.

Common situations: Expired or missing Kerberos ticket/keytab causing GSS-API failures; misconfigured service principal (spnego service name); network interruptions mid-call; users inspecting the message and forgetting to check getCause().

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10). Data as JSON: /api/errors/d7b122c507e3a326. Report an issue: GitHub.