apache/seatunnel · error · ConfigCheckException

No upstream source or transform is available for sink.

Error message

No upstream source or transform is available for sink.

What it means

findLast returns the last entry of an ordered map of upstream vertices (used to pick the single input for a transform or sink during dry-run validation). If the map is empty — meaning no source or transform produced an output vertex upstream of the plugin — it throws ConfigCheckException('No upstream source or transform is available for sink.'). It catches configs where a sink (or transform chain) has no reachable upstream producer.

Source

Thrown at seatunnel-core/seatunnel-starter/src/main/java/org/apache/seatunnel/core/starter/seatunnel/command/DryRunConnectValidator.java:447

                throw new ConfigCheckException(
                        location(pluginType, configIndex, factoryId)
                                + " does not support processing inputs with different schemas. "
                                + "Expected table "
                                + expected.getTableId()
                                + " but found table "
                                + catalogTable.getTableId()
                                + ".");
            }
        }
    }

    private List<String> getInputIds(ReadonlyConfig config) {
        return config.getOptional(PLUGIN_INPUT).orElse(Collections.singletonList(DEFAULT_ID));
    }

    private <T> T findLast(LinkedHashMap<?, T> map) {
        if (map.isEmpty()) {
            throw new ConfigCheckException(
                    "No upstream source or transform is available for sink.");
        }
        T result = null;
        for (T value : map.values()) {
            result = value;
        }
        return result;
    }

    private void logSummary(List<PluginResult> results) {
        StringBuilder summary = new StringBuilder("Dry-run connect validation summary:");
        for (PluginResult result : results) {
            summary.append(System.lineSeparator()).append("  ").append(result);
        }
        log.info(summary.toString());
    }

    private ConfigCheckException wrap(

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Ensure a source block exists and its plugin_output matches the sink's plugin_input exactly.
  2. Remove or fix invalid plugin_input references; sinks without plugin_input default to the DEFAULT_ID producer.
  3. Run with --dry-run CONNECT after fixing to re-validate the DAG.

Example fix

// before
sink {
  Console { plugin_input = src_typo }
}
// after
source {
  FakeSource { plugin_output = "src"; result_table_name = "src" }
}
sink {
  Console { plugin_input = "src" }
}
Defensive patterns

Strategy: validation

Validate before calling

// every sink/transform must reference an existing upstream output id
const outputIds = new Set([...sources, ...transforms].flatMap(p => outputsOf(p)));
for (const p of [...transforms, ...sinks]) {
  for (const input of inputsOf(p)) {
    if (!outputIds.has(input)) throw new Error("No upstream producer for input id: " + input);
  }
}

Try / catch

try { validateConf(conf, DryRun.CONNECT); } catch (ConfigCheckException e) { if (e.getMessage().contains("No upstream source or transform is available")) { fixPluginInputWiring(conf); } else { throw e; } }

Prevention

When it happens

Trigger: A sink block whose referenced plugin_input id matches no source/transform output, or a sink defined with no source at all in the config; the upstream map built during validation is empty when validateSink/validateTransform calls findLast.

Common situations: Typos or case mismatches in plugin_input/plugin_output ids; config file missing the source block entirely; commented-out source while the sink remains.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/21d8afaaabda8464. Report an issue: GitHub.