apache/seatunnel · warning

CloseScanner result from {} is null.

Error message

CloseScanner result from {} is null.

What it means

closeScanner sends TScanCloseParams to release the BE scan context. If the RPC returns null it logs this warning and retries; after retries the method proceeds to close the client regardless. Because scanner close is best-effort cleanup, a null response usually just means the scan context release could not be confirmed — leaked scan contexts on the BE are the practical consequence.

Source

Thrown at seatunnel-connectors-v2/connector-doris/src/main/java/org/apache/seatunnel/connectors/doris/backend/BackendClient.java:235

        log.error(ErrorMessages.CONNECT_FAILED_MESSAGE, routing);
        //        throw new ConnectedFailedException(routing.toString(), ex);
        throw new DorisConnectorException(
                DorisConnectorErrorCode.SCAN_BATCH_FAILED, routing.toString(), ex);
    }

    /**
     * close a scanner.
     *
     * @param closeParams thrift struct to required by request
     */
    public void closeScanner(TScanCloseParams closeParams) {
        log.debug("CloseScanner to '{}', parameter is '{}'.", routing, closeParams);
        for (int attempt = 0; attempt < retries; ++attempt) {
            log.debug("Attempt {} to closeScanner {}.", attempt, routing);
            try {
                TScanCloseResult result = client.closeScanner(closeParams);
                if (result == null) {
                    log.warn("CloseScanner result from {} is null.", routing);
                    continue;
                }
                if (!TStatusCode.OK.equals(result.getStatus().getStatusCode())) {
                    log.warn(
                            "The status of get next result from {} is '{}', error message is: {}.",
                            routing,
                            result.getStatus().getStatusCode(),
                            result.getStatus().getErrorMsgs());
                    continue;
                }
                break;
            } catch (TException e) {
                log.warn("Close scanner from {} failed.", routing, e);
            }
        }
        log.info("CloseScanner to Doris BE '{}' success.", routing);
        close();
    }

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Usually safe to ignore if the read already completed; the context will expire on the BE.
  2. If contexts leak, check/expire them on the BE (ADMIN CLEAN; monitor scan contexts) or restart the BE.
  3. Verify BE logs for prior cancellation of the context.
  4. Ensure connector and Doris versions match to avoid protocol-level null responses.
Defensive patterns

Strategy: retry

Try / catch

// closeScanner is best-effort; no exception escapes, so no catch is needed.
// After the read completes, optionally verify the BE did not leak scan contexts.

Prevention

When it happens

Trigger: client.closeScanner(closeParams) returns null on all retry attempts — typically because the scan context was already terminated (BE restart, expired context, prior getNext failure) or the BE returned an unexpected empty response.

Common situations: Cleanup after an earlier read failure or job cancellation; BE restarting during teardown; version/protocol mismatch.

Understand the failure class

Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.

Related errors


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