apache/shenyu · error · RuntimeException
Import failed:
Error message
Import failed:
What it means
importSwagger() wraps any unexpected exception from the swagger import pipeline into a RuntimeException with the prefix 'Import failed: ' plus the underlying message. It is a catch-all so the controller gets a single failure path, while IllegalArgumentException (bad user input) is deliberately re-thrown unwrapped so the controller can map it to HTTP 400. Seeing this message means the import failed for a non-validation reason (IO, parsing, downstream service errors).
Solutions
- Read the 'cause' stack trace of this RuntimeException to find the real failure (IO error, parse error, etc.) — the wrapper message alone is not diagnostic.
- Verify the swaggerUrl is reachable from the admin server (curl it from the same host/network).
- Confirm the document is valid Swagger 2.0/OpenAPI 3.0 JSON so it passes validateSwaggerContent before deeper processing.
- If it should be a 400-style validation problem, throw IllegalArgumentException in the underlying code instead of a generic Exception so it is not wrapped.
Example fix
// before: service throws generic exception which gets wrapped
throw new Exception("something broke");
// after: use IllegalArgumentException for user-input problems so controller returns 400
throw new IllegalArgumentException("projectName must not be blank"); Defensive patterns
Strategy: try-catch
Validate before calling
try (Response r = new OkHttpClient().newCall(new Request.Builder().url(swaggerUrl).build()).execute()) {
if (r.code() != 200 || r.body() == null) throw new IllegalStateException("swagger URL not fetchable: " + r.code());
JsonParser.parseString(r.body().string()); // must be parseable JSON
} Try / catch
try {
swaggerImportService.importSwagger(request);
} catch (IllegalArgumentException e) {
return ResponseEntity.badRequest().body(e.getMessage()); // validation problem
} catch (RuntimeException e) {
log.error("import failed", e.getCause()); // inspect cause for the real error
return ResponseEntity.status(502).body("import failed: " + e.getCause().getMessage());
} Prevention
- Always log/read e.getCause() — the wrapper message is never the root cause.
- Pre-validate the swagger URL with a curl/HEAD request before importing.
- Validate swagger content client-side before calling the import API.
- Distinguish validation failures (400) from infrastructure failures (5xx) in your caller code.
When it happens
Trigger: Calling the swagger import API (SwaggerImportServiceImpl.importSwagger) when any step throws a non-IllegalArgumentException Exception: reading/fetching the swagger document fails, JSON parsing blows up unexpectedly, or downstream registration code throws. The original cause is attached as the cause of the RuntimeException.
Common situations: The swagger URL points to a service that is down or returns garbage; the admin server cannot reach the target host; the document passes basic validation but fails later parsing/mapping; database or namespace registration steps fail mid-import.
Understand the failure class
Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.
Related errors
- Import mcp server config failed:
- Failed to get Swagger document, HTTP status code:
- Unsupported Swagger version, only Swagger 2.0 and OpenAPI…
- Invalid Swagger JSON format:
AI-assisted analysis of apache/shenyu@567142e072 (2026-09-12).
Data as JSON: /api/errors/494cd184f008194c.
Report an issue: GitHub.
Appendix: source
Thrown at shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/SwaggerImportServiceImpl.java:119
// 4. Create virtual instance
UpstreamInstance instance = createVirtualInstance(request);
// 5. Parse and save document
docManager.addDocInfo(instance, swaggerJson, null, docInfo -> {
LOG.info("Successfully imported swagger document: {} with MD5: {}",
request.getProjectName(), docInfo.getDocMd5());
});
return "Import successful, supports Swagger 2.0 and OpenAPI 3.0 formats";
} catch (IllegalArgumentException e) {
// Keep bad user input unwrapped so the controller can return HTTP 400.
LOG.error("Failed to import swagger document: {}", request.getProjectName(), e);
throw e;
} catch (Exception e) {
LOG.error("Failed to import swagger document: {}", request.getProjectName(), e);
throw new RuntimeException("Import failed: " + e.getMessage(), e);
}
}
@Override
public String importMcpConfig(final SwaggerImportRequest request) {
LOG.info("Start importing Mcp config: {}", request);
try {
validateSwaggerUrl(request.getSwaggerUrl());
String swaggerJson = fetchSwaggerDoc(request.getSwaggerUrl());
String namespaceId = StringUtils.defaultIfEmpty(request.getNamespaceId(), SYS_DEFAULT_NAMESPACE_ID);
List<McpToolsRegisterDTO> mcpToolsRegisterDTOList = buildMcpToolRegisterDTO(swaggerJson, namespaceId);
mcpToolsRegisterDTOList.forEach(mcpToolsRegisterDTO -> {
shenyuClientRegisterMcpService.registerMcpTools(mcpToolsRegisterDTO);
});View on GitHub (pinned to 567142e072)