{"record":{"id":"ea7e2299c2ebe492","repo":"apache/seatunnel","slug":"handle-save-mode-failed-ea7e22","errorCode":"HANDLE_SAVE_MODE_FAILED","errorMessage":"All candidate sink tables were skipped during cluster save mode.","messagePattern":"All candidate sink tables were skipped during cluster save mode\\.","errorType":"error_code","errorClass":"SeaTunnelRuntimeException","httpStatus":null,"severity":"error","filePath":"seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/master/JobMaster.java","lineNumber":832,"sourceCode":"                                    entry.getValue().getPluginName(),\n                                    error);\n                    failedTables.add(failedTable);\n                    LOGGER.warning(\n                            \"Skip failed sink table during cluster save mode: \"\n                                    + MultiTableFailureHelper.formatFailedTableLine(failedTable),\n                            error);\n                }\n            }\n            if (failedTables.isEmpty()) {\n                return;\n            }\n\n            failedTables.forEach(\n                    failedTable ->\n                            multiTableSink.removeSink(TablePath.of(failedTable.getTablePath())));\n            multiTableSink.registerInitialFailedTables(failedTables);\n            if (multiTableSink.getSinks().isEmpty()) {\n                throw new SeaTunnelRuntimeException(\n                        HANDLE_SAVE_MODE_FAILED,\n                        new IllegalStateException(\n                                MultiTableFailureHelper.formatFailedTableSummary(\n                                        \"All candidate sink tables were skipped during cluster save mode.\",\n                                        failedTables)));\n            }\n        }\n    }\n\n    public void handleCheckpointError(long pipelineId, boolean neverRestore) {\n        if (neverRestore) {\n            this.neverNeedRestore();\n        }\n        this.physicalPlan\n                .getPipelineList()\n                .forEach(\n                        pipeline -> {\n                            if (pipeline.getPipelineLocation().getPipelineId() == pipelineId) {","sourceCodeStart":814,"sourceCodeEnd":850,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/master/JobMaster.java#L814-L850","documentation":"During cluster save-mode handling, JobMaster.handleSaveMode applies each sink table's save-mode (e.g. drop/create) and collects tables that failed. Failed tables are removed from the MultiTableSink and registered as initial failures; if that leaves zero sinks, nothing can be written, so a SeaTunnelRuntimeException with code HANDLE_SAVE_MODE_FAILED is thrown containing a formatted summary of all failed tables.","triggerScenarios":"Running a multi-table sink job in cluster save mode where EVERY candidate sink table's save-mode execution failed (e.g. DROP TABLE failed for all tables due to permissions or connection issues), leaving multiTableSink empty.","commonSituations":"Sink user lacking DROP/CREATE privileges on all target tables; database unreachable; wrong catalog/table paths configured for all tables; schema mismatches causing every table's save-mode step to be skipped.","solutions":["Inspect the formatted failed-table summary in the exception to see each table's root failure and fix the per-table cause (permissions, connection, table path).","Grant the sink user the privileges required by the configured save mode (e.g. DROP/CREATE TABLE).","Verify catalog configuration and table paths for the sink tables.","Change the save mode (e.g. from DROP to CREATE_OR_REPLACE/ERROR) to one that can succeed for these tables."],"exampleFix":"// before\nsink {\n  Jdbc {\n    save_mode = \"drop\"\n  }\n}\n// after: use a less privileged save mode\nsink {\n  Jdbc {\n    save_mode = \"error\"\n  }\n}","handlingStrategy":"validation","validationCode":"// preflight: test save-mode privilege per sink table\nfor (TablePath t : sinkTables) {\n    if (!catalog.tableExists(t) && saveModeRequiresExisting(t)) {\n        fail(\"table missing and save mode cannot create it: \" + t);\n    }\n}\nif (failedTables.size() == sinkTables.size()) fail(\"all sink tables will be skipped\");","typeGuard":null,"tryCatchPattern":"try {\n    submitJob(conf);\n} catch (SeaTunnelRuntimeException e) {\n    if (\"HANDLE_SAVE_MODE_FAILED\".equals(e.getSeaTunnelErrorCode().getCode())) {\n        log.error(\"save-mode failed summary: {}\", e.getMessage()); // inspect per-table causes\n    }\n    throw e;\n}","preventionTips":["Grant the sink user the DDL privileges required by the configured save mode.","Test save mode against a staging database before production runs.","Validate catalog config and table paths for every sink table in the job."],"tags":["sink","save-mode","multi-table","job-failed"],"backgroundTag":"empty-result-set","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}