apache/seatunnel · error · CommandExecuteException
Failed to export metadata
Error message
Failed to export metadata
What it means
MetadataExportCommand.execute writes the exported connector metadata (plugin identifiers, option rules) to the output JSON file. Any IOException encountered while creating or writing that file is rethrown as CommandExecuteException('Failed to export metadata', e). The export logic itself succeeded in enumerating connectors; the failure is purely on the output-file side.
Source
Thrown at seatunnel-core/seatunnel-starter/src/main/java/org/apache/seatunnel/core/starter/seatunnel/command/MetadataExportCommand.java:134
connectorsArray.add(connectorNode);
}
}
root.set("connectors", connectorsArray);
if (args.isStdout()) {
System.out.println(mapper.writeValueAsString(root));
} else {
File outputFile = new File(args.getOutputPath());
mapper.writeValue(outputFile, root);
System.err.println(
"Exported "
+ connectorsArray.size()
+ " connectors to "
+ outputFile.getAbsolutePath());
}
} catch (IOException e) {
throw new CommandExecuteException("Failed to export metadata", e);
}
}
private ObjectNode exportConnector(
PluginIdentifier id, OptionRule rule, PluginType pluginType) {
ObjectNode node = mapper.createObjectNode();
node.put("name", id.getPluginName());
node.put("type", pluginType.getType());
// Required options — preserving the 4 subtypes
ArrayNode requiredArray = mapper.createArrayNode();
for (RequiredOption reqOpt : rule.getRequiredOptions()) {
String category = resolveCategory(reqOpt);
String expression = null;
if (reqOpt instanceof RequiredOption.ConditionalRequiredOptions) {
Expression expr =
((RequiredOption.ConditionalRequiredOptions) reqOpt).getExpression();View on GitHub (pinned to cf67b549a7)
Solutions
- Check the nested IOException cause for the exact filesystem reason.
- Verify the output path's parent directory exists and is writable by the running user; create it or choose another path.
- Check disk space and file permissions (ls -ld on the target directory).
- If running in a container, ensure the volume is mounted and the user has write access.
Example fix
// before seatunnel.sh -m --output /root/only/meta.json # non-root user // after mkdir -p /tmp/seatunnel-meta seatunnel.sh -m --output /tmp/seatunnel-meta/meta.json
Defensive patterns
Strategy: validation
Validate before calling
const dir = path.dirname(outputFile);
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
fs.accessSync(dir, fs.constants.W_OK); // throws early if unwritable Try / catch
try { exportMetadata(args); } catch (CommandExecuteException e) { if (e.getMessage().equals("Failed to export metadata")) { log.error("Check output path/permissions/disk: ", e.getCause()); } else { throw e; } } Prevention
- Pre-create the output directory and verify write permissions
- Avoid exporting to root-owned or read-only paths from non-root users
- Check free disk space before large exports
When it happens
Trigger: The --output path is unwritable (permission denied, read-only filesystem), its parent directory does not exist, the path is a directory, or disk is full while the Jackson writer flushes the connectors array.
Common situations: Running in a container as non-root writing to a root-owned path; typo in the output directory; overwriting a file locked or owned by another user; exporting to a mounted volume not yet mounted.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
- create(): Mkdirs failed to create: %s
- Failed to persist failure sample to '{}'; disabling failure-
- Failed to close failure-data writer. cause={}
- Circular condition chain detected: '%s' already exists in th
- Condition for option '%s' has a null operator
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/bbfde83ac34b9ead.
Report an issue: GitHub.