apache/shardingsphere · error · FileIOException
30020
30020
Error message
File access failed, file is: %s
What it means
FileIOException (error code 30020) thrown by ImportMetaDataExecutor.getMetaDataFromFile when reading the file given to IMPORT METADATA fails. If the statement supplies a file path (Optional is present), FileUtils.readFileToString(file, Charset.defaultCharset()) is used; any IOException (missing/unreadable file, broken encoding) is replaced by FileIOException naming the file. This path applies only when filePath is present — the console (base64) variant reads getMetaDataValue() instead.
Source
Thrown at proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/updatable/imports/ImportMetaDataExecutor.java:56
public final class ImportMetaDataExecutor implements DistSQLUpdateExecutor<ImportMetaDataStatement> {
@Override
public void executeUpdate(final ImportMetaDataStatement sqlStatement, final ContextManager contextManager) {
String jsonMetaDataConfig = sqlStatement.getFilePath().isPresent() ? getMetaDataFromFile(sqlStatement) : getMetaDataFromConsole(sqlStatement);
ExportedClusterInfo exportedClusterInfo = JsonUtils.fromJsonString(jsonMetaDataConfig, ExportedClusterInfo.class);
ExportedMetaData exportedMetaData = exportedClusterInfo.getMetaData();
new MetaDataImportExecutor(contextManager).importClusterConfigurations(exportedMetaData);
}
private String getMetaDataFromFile(final ImportMetaDataStatement sqlStatement) {
if (!sqlStatement.getFilePath().isPresent()) {
return "";
}
File file = new File(sqlStatement.getFilePath().get());
try {
return FileUtils.readFileToString(file, Charset.defaultCharset());
} catch (final IOException ignore) {
throw new FileIOException(file);
}
}
private String getMetaDataFromConsole(final ImportMetaDataStatement sqlStatement) {
return new String(Base64.decodeBase64(sqlStatement.getMetaDataValue()));
}
@Override
public Class<ImportMetaDataStatement> getType() {
return ImportMetaDataStatement.class;
}
}
View on GitHub (pinned to e952770a21)
Solutions
- Ensure the metadata file exists on every proxy node that may execute the IMPORT, using an absolute path
- Fix read permissions for the proxy process user
- Alternatively use the console form (IMPORT METADATA FROM ...) with the base64 content, which bypasses file access entirely
Example fix
-- before IMPORT METADATA FROM FILE 'metadata/export.json'; -- after IMPORT METADATA FROM FILE '/opt/shardingsphere/metadata/export.json';
Defensive patterns
Strategy: validation
Validate before calling
if (statement.getFilePath().isPresent()) {
File f = new File(statement.getFilePath().get());
if (!f.isFile() || !f.canRead()) {
throw new IllegalArgumentException("Metadata file unavailable: " + f.getAbsolutePath());
}
} Prevention
- Distribute the metadata file to all proxy nodes or use the console (base64) import form
- Verify checksum of transferred export files before running IMPORT METADATA
When it happens
Trigger: IMPORT METADATA FROM FILE '/path/metadata.json' (or equivalent) where the path is absent, unreadable, or reading fails with IOException; IMPORT METADATA without a file path does not hit this code.
Common situations: Metadata migration between clusters where the exported file was not transferred to the new proxy node; wrong working directory for a relative path; multi-node cluster where only one node has the file.
Related errors
AI-assisted analysis of apache/shardingsphere@e952770a21 (2026-08-14).
Data as JSON: /api/errors/355cfce6ba53247f.
Report an issue: GitHub.