apache/incubator-seata · error · ServiceCallException

MCP PUT Call TC Failed.

Error message

MCP PUT Call TC Failed.

What it means

Thrown when the RestTemplate/RestClient PUT call from the Seata console MCP service to the TC fails at the transport level (RestClientException): connection refused, DNS failure, connect/read timeout, or TLS problems. It is distinct from error 120, which covers a completed HTTP exchange with a bad status; here the exchange never completed.

Source

Thrown at console/src/main/java/org/apache/seata/mcp/service/impl/ConsoleRemoteServiceImpl.java:247

        HttpEntity<String> entity = new HttpEntity<>(headers);
        String responseBody;
        try {
            ResponseEntity<String> response = executeRequest(url, HttpMethod.PUT, entity);

            responseBody = response.getBody();

            if (!response.getStatusCode().is2xxSuccessful()) {
                String errorMsg = String.format(
                        "MCP PUT request returned non-success status: %s, response: %s",
                        response.getStatusCode(), response.getBody());
                LOGGER.warn(errorMsg);
                throw new ServiceCallException(errorMsg, response.getStatusCode());
            }
            return responseBody;
        } catch (RestClientException e) {
            String errorMsg = "MCP PUT Call TC Failed.";
            LOGGER.error(errorMsg, e);
            throw new ServiceCallException(errorMsg);
        }
    }

    private ResponseEntity<String> executeRequest(String url, HttpMethod httpMethod, HttpEntity<String> entity)
            throws RestClientException {
        return restClient
                .method(Objects.requireNonNull(httpMethod))
                .uri(Objects.requireNonNull(url))
                .headers(headers -> headers.addAll(entity.getHeaders()))
                .exchange((request, response) -> new ResponseEntity<>(
                        readResponseBody(response), response.getHeaders(), response.getStatusCode()));
    }

    private String readResponseBody(RestClient.RequestHeadersSpec.ConvertibleClientHttpResponse response)
            throws IOException {
        return response.getBody() == null ? "" : StreamUtils.copyToString(response.getBody(), StandardCharsets.UTF_8);
    }
}

View on GitHub (pinned to e01f97c6db)

Solutions

  1. Confirm the TC process is up: check port listening (e.g. ss -ltnp | grep <tc-port>) and TC health endpoint.
  2. Fix connectivity: correct host/port in the console MCP remote configuration, open firewall/security-group rules, fix DNS.
  3. If timeouts, raise the console HTTP client read/connect timeout settings to cover slow TC operations.
  4. For HTTPS failures, import the TC certificate into the console JVM truststore instead of disabling verification.

Example fix

// before: TC not started / wrong host
String url = "http://wrong-host:7091/api/v1/...";
// after: verified reachable TC endpoint
String url = "http://tc-host:7091/api/v1/...";
Defensive patterns

Strategy: retry

Validate before calling

// preflight: resolve + connect to TC before issuing PUT
InetSocketAddress a = new InetSocketAddress(host, port);
if (a.isUnresolved()) throw new IllegalStateException("TC host unresolved: " + host);
try (Socket s = new Socket()) { s.connect(a, 2000); }

Try / catch

catch (ServiceCallException e) {
    Throwable cause = e.getCause(); // RestClientException
    if (cause instanceof ConnectException) { /* wait for TC, then retry */ }
    else if (cause instanceof ResourceAccessException && cause.getCause() instanceof SocketTimeoutException) { raiseTimeout(); }
    else { escalate; }
}

Prevention

When it happens

Trigger: executing an MCP tool that triggers executeRequest(url, PUT, entity) while the TC host is down, the configured hostname does not resolve, a firewall drops the connection, the connect/read timeout is exceeded, or an HTTPS endpoint presents an untrusted certificate.

Common situations: TC process stopped or crashed, console started before TC in docker-compose (race at startup), wrong host/port in console config, network policy blocking the console->TC path, or self-signed TLS on TC without the CA in the console truststore.

Related errors


AI-assisted analysis of apache/incubator-seata@e01f97c6db (2026-08-14). Data as JSON: /api/errors/029c81776546a719. Report an issue: GitHub.