strapi/strapi · error · Error
restore failed ${error}
Error message
restore failed ${error} What it means
Thrown by beforeTransfer() as a catch-all wrapper around the restore preparation steps: #handleAssetsBackup(), #deleteAllAssets(trx), and #deleteFromRestoreOptions(). The original error is stringified into the message. It runs inside a transaction.attach() callback, so the transaction will be rolled back by the engine on failure. The inner error could be a file-system failure, a database error, or a missing-options error.
Source
Thrown at packages/core/data-transfer/src/strapi/providers/local-destination/index.ts:193
this.options.onTransferPhase?.('Local: preparing destination for restore…');
await this.transaction?.attach(async (trx) => {
try {
if (this.options.strategy === 'restore') {
if (this.#areAssetsIncluded()) {
this.options.onTransferPhase?.('Local: backing up existing upload folder…');
}
await this.#handleAssetsBackup();
if (this.#areAssetsIncluded()) {
this.options.onTransferPhase?.('Local: deleting existing media files from disk…');
}
await this.#deleteAllAssets(trx);
this.options.onTransferPhase?.('Local: clearing database content for restore…');
await this.#deleteFromRestoreOptions();
}
} catch (error) {
throw new Error(`restore failed ${error}`);
}
});
}
getMetadata(): IMetadata {
this.#reportInfo('getting metadata');
assertValidStrapi(this.strapi, 'Not able to get Schemas');
const strapiVersion = this.strapi.config.get<string>('info.strapi');
const createdAt = new Date().toISOString();
return {
createdAt,
strapi: {
version: strapiVersion,
},
};
}
View on GitHub (pinned to 4a4101264d)
Solutions
- Inspect the inner error (the part after 'restore failed ') to identify which sub-step failed.
- For filesystem errors, check write permissions on strapi.dirs.static.public and the uploads subdirectory.
- For database errors, check database connectivity, locks, and constraints.
- For upload-provider errors, verify the upload provider configuration and that referenced files exist.
- Re-run the transfer after fixing the root cause; the transaction rollback ensures the database is in a consistent pre-transfer state.
Defensive patterns
Strategy: try-catch
Try / catch
try {
await provider.beforeTransfer();
} catch (e) {
const msg = e instanceof Error ? e.message : String(e);
if (msg.startsWith('restore failed ')) {
const inner = msg.slice('restore failed '.length);
console.error('Restore preparation failed. Root cause:', inner);
// The transaction is rolled back; the DB is in its pre-transfer state.
} else {
throw e;
}
} Prevention
- Pre-flight check: verify filesystem permissions on public/uploads before starting.
- Pre-flight check: verify database connectivity.
- Inspect the inner error string after 'restore failed ' to find the sub-step that failed.
- The transaction rollback ensures consistency — safe to retry after fixing the root cause.
When it happens
Trigger: Any failure during the restore preparation phase: the uploads directory lacks write permissions (assets backup fails), a database query in deleteMany fails, the upload provider's delete() throws for a file, or #deleteFromRestoreOptions hits a missing restore option.
Common situations: Insufficient filesystem permissions on the public/uploads directory. A corrupt or locked database row during deleteMany. A custom upload provider whose delete() throws on missing files. Disk full during the backup move operation.
Related errors
- ASSETS_DIRECTORY_ERR
- Path '${root}' is not a directory.
- Directory '${root}' is not a valid Strapi data export.
- Missing ${METADATA_FILE_PATH} in export directory '${this.#r
- Could not read backup file path provided at "${this.options.
AI-assisted analysis of strapi/strapi@4a4101264d (2026-08-12).
Data as JSON: /api/errors/953317675971e60c.
Report an issue: GitHub.