{"record":{"id":"8a7d4ce25a566372","repo":"spring-projects/spring-security","slug":"doexecute-returned-null","errorCode":null,"errorMessage":"doExecute returned null","messagePattern":"doExecute returned null","errorType":"http","errorClass":"RestClientException","httpStatus":null,"severity":"error","filePath":"kerberos/kerberos-client/src/main/java/org/springframework/security/kerberos/client/KerberosRestTemplate.java","lineNumber":264,"sourceCode":"\t\t\t\t\t\t\tresponseExtractor);\n\t\t\t\t}\n\t\t\t});\n\n\t\t}\n\t\tcatch (RestClientException ex) {\n\t\t\tthrow ex;\n\t\t}\n\t\tcatch (Exception ex) {\n\t\t\tthrow new RestClientException(\"Error running rest call\", ex);\n\t\t}\n\t}\n\n\tprivate <T> T doExecuteSubject(URI url, @Nullable String uriTemplate, @Nullable HttpMethod method,\n\t\t\t@Nullable RequestCallback requestCallback, @Nullable ResponseExtractor<T> responseExtractor)\n\t\t\tthrows RestClientException {\n\t\tT result = super.doExecute(url, uriTemplate, method, requestCallback, responseExtractor);\n\t\tif (result == null) {\n\t\t\tthrow new RestClientException(\"doExecute returned null\");\n\t\t}\n\t\treturn result;\n\t}\n\n\tprivate static final class ClientLoginConfig extends Configuration {\n\n\t\tprivate final @Nullable String keyTabLocation;\n\n\t\tprivate final @Nullable String userPrincipal;\n\n\t\tprivate final @Nullable String password;\n\n\t\tprivate final @Nullable Map<String, Object> loginOptions;\n\n\t\tprivate ClientLoginConfig(@Nullable String keyTabLocation, @Nullable String userPrincipal,\n\t\t\t\t@Nullable String password, @Nullable Map<String, Object> loginOptions) {\n\t\t\tsuper();\n\t\t\tthis.keyTabLocation = keyTabLocation;","sourceCodeStart":246,"sourceCodeEnd":282,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/kerberos/kerberos-client/src/main/java/org/springframework/security/kerberos/client/KerberosRestTemplate.java#L246-L282","documentation":"doExecuteSubject calls RestTemplate's doExecute and asserts the result is non-null before returning it. Since KerberosRestTemplate always uses a ResponseExtractor, a null result would indicate an unexpected/failed extraction, so it throws RestClientException('doExecute returned null') to keep the return contract of T non-null.","triggerScenarios":"Executing a request via KerberosRestTemplate where super.doExecute returns null — typically when the supplied ResponseExtractor.extractData returns null or no extractor produced a value.","commonSituations":"Custom ResponseExtractor implementations that return null on empty bodies; extractors that forget to return the parsed value on some code path.","solutions":["Fix the ResponseExtractor to never return null (return an empty object/empty collection instead).","Wrap the call in try-catch and substitute a default value when this RestClientException is thrown.","Use built-in extractors (e.g. getForObject) rather than a hand-written one that can return null."],"exampleFix":"// before\npublic String extractData(ClientHttpResponse r) { parse(r); } // returns null\n// after\npublic String extractData(ClientHttpResponse r) { return parse(r); }","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    return template.execute(url, HttpMethod.GET, null, extractor);\n} catch (RestClientException e) {\n    if (\"doExecute returned null\".equals(e.getMessage())) {\n        return defaultValue; // extractor produced null\n    }\n    throw e;\n}","preventionTips":["Never return null from ResponseExtractor.extractData; return empty collections/objects.","Unit-test custom extractors against empty response bodies.","Prefer built-in conversion (getForObject) over hand-rolled extractors."],"tags":["java","kerberos","resttemplate","null","response-extractor"],"backgroundTag":"empty-api-response","analyzedSha":"96852e8860138a482cb13d1479573f24ff6443c6","analyzedAt":"2026-09-10T23:25:23.477Z","contentChangedAt":"2026-09-10T23:25:23.477Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}