How to parse the response body in Java, when the HTTP request has return status 401

Try the following approach without needing a custom handler. The idea is to get the response as a string from the HttpStatusCodeException, and then you can convert it to your object. For the conversion I used the Jackson's ObjectMapper:

        try {

            restTemplate.postForObject(url, pojoInstance, responseClass);

        } catch (HttpStatusCodeException e) {

            if (e.getStatusCode() == HttpStatus.UNAUTHORIZED) {

                String responseString = e.getResponseBodyAsString();

                ObjectMapper mapper = new ObjectMapper();

                CustomError result = mapper.readValue(responseString,
                        CustomError.class);
            }
        }

Update: Usage of a different factory may also help since there is a bug in the default one related to your issue (see comment below):

RestTemplate template = new RestTemplate(new HttpComponentsClientHttpRequestFactory());

I did it like that:

@Component
public class RestTemplateFactory {
public enum Type {
    JSON, XML
}

public RestTemplate create(Type type) {
    RestTemplate restTemplate = new RestTemplate();
    if (type == Type.XML) {
        Jaxb2RootElementHttpMessageConverter jaxbMessageConverter = new Jaxb2RootElementHttpMessageConverter();
        jaxbMessageConverter.setSupportedMediaTypes(Lists.newArrayList(MediaType.TEXT_HTML, MediaType.APPLICATION_XML));
        restTemplate.setMessageConverters(Lists.newArrayList(jaxbMessageConverter));
    }
    restTemplate.setErrorHandler(new BpmRestErrorHandler(restTemplate.getMessageConverters()));
    return restTemplate;
}

public HttpHeaders contentHeaders(Type type) {
    HttpHeaders headers = new HttpHeaders();
    if (type == Type.XML) {
        headers.setContentType(MediaType.APPLICATION_XML);
        headers.setAccept(Collections.singletonList(MediaType.APPLICATION_XML));
    } else {
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
    }
    return HttpHeaders.readOnlyHttpHeaders(headers);
}
}

And handler:

public class BpmRestErrorHandler extends DefaultResponseErrorHandler {

private final List<HttpMessageConverter<?>> messageConverters;

public BpmRestErrorHandler(List<HttpMessageConverter<?>> messageConverters) {
    this.messageConverters = messageConverters;
}

@Override
public void handleError(ClientHttpResponse response) throws IOException {
    for (HttpMessageConverter messageConverter : messageConverters) {
        if (messageConverter.canRead(RestRuntimeException.class, response.getHeaders().getContentType())) {
            RestRuntimeExceptionData exceptionData =
                    (RestRuntimeExceptionData)messageConverter.read(RestRuntimeException.class, response);
            throw new BpmRestException(exceptionData);
        }
    }
    super.handleError(response);
}
}

Where RestRuntimeExceptionData is my custom WebFault object. It re-uses RestTemplate's HttpConverters.