apache/seatunnel · error · IllegalArgumentException

Azure Queue Storage source expects exactly one source split

Error message

Azure Queue Storage source expects exactly one source split

What it means

AzureQueueStorageSourceReader.addSplits() enforces the single-split invariant: this connector reads one queue per reader, so exactly one split must be delivered. Receiving zero or multiple splits throws IllegalArgumentException.

Source

Thrown at seatunnel-connectors-v2/connector-azure-queue-storage/src/main/java/org/apache/seatunnel/connectors/seatunnel/azure/queue/source/AzureQueueStorageSourceReader.java:142

                        "Failed to process Azure Queue Storage message " + message.getMessageId(),
                        e);
            }
        }
        checkVisibilityRenewalFailure();
    }

    @Override
    public List<SingleSplit> snapshotState(long checkpointId) {
        synchronized (acknowledgementLock) {
            pendingAcknowledgements.put(checkpointId, new ArrayList<>(unacknowledgedMessages));
        }
        return Collections.singletonList(new SingleSplit(null));
    }

    @Override
    public void addSplits(List<SingleSplit> splits) {
        if (splits.size() != 1) {
            throw new IllegalArgumentException(
                    "Azure Queue Storage source expects exactly one source split");
        }
        if (splitAssigned) {
            return;
        }

        receiver = receiverFactory.create();
        visibilityRenewalExecutor =
                Executors.newSingleThreadScheduledExecutor(
                        runnable -> {
                            Thread thread = new Thread(runnable, "azure-queue-visibility-renewal");
                            thread.setDaemon(true);
                            return thread;
                        });
        long renewalIntervalSeconds = Math.max(1L, config.getVisibilityTimeoutSeconds() / 3L);
        visibilityRenewalExecutor.scheduleWithFixedDelay(
                this::renewVisibilitySafely,
                renewalIntervalSeconds,

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Ensure source parallelism matches the single-split enumerator (parallelism 1 for a single queue)
  2. Update the connector to a version fixing split enumeration
  3. If custom, fix the enumerator to return exactly one SingleSplit

Example fix

// before (custom enumerator)
return Arrays.asList(new SingleSplit(null), new SingleSplit(null));
// after
return Collections.singletonList(new SingleSplit(null));
Defensive patterns

Strategy: try-catch

Validate before calling

if (splits.size() != 1) throw new IllegalStateException("expected exactly one split");

Try / catch

try {
    reader.addSplits(splits);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("exactly one source split")) {
        LOG.error("Split enumeration returned {} splits; expected 1", splits.size());
    }
    throw e;
}

Prevention

When it happens

Trigger: The split enumerator/assignSplit path delivers a list whose size != 1 to addSplits() — e.g. a parallelism/enum bug, custom code, or framework passing an empty list.

Common situations: Running with misconfigured parallelism assumptions, internal connector bugs, or embedding the connector with a custom enumerator that generates multiple SingleSplits.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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