apache/pulsar · error · RuntimeException

Effectively-once processing guarantees not yet supported in

Error message

Effectively-once processing guarantees not yet supported in Python

What it means

Python runtime functions do not support EFFECTIVELY_ONCE processing guarantees. doPythonChecks throws a RuntimeException when a function config targeting the Python runtime requests that guarantee level.

Source

Thrown at pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/FunctionConfigUtils.java:753

            ValidatorUtils.validateSerde(functionConfig.getOutputSerdeClassName(), typeArgs[1],
                    validatableFunctionPackage.getTypePool(), false);
        }

        if (functionConfig.getProducerConfig() != null
                && functionConfig.getProducerConfig().getCryptoConfig() != null) {
            ValidatorUtils
                    .validateCryptoKeyReader(functionConfig.getProducerConfig().getCryptoConfig(),
                            validatableFunctionPackage.getTypePool(), true);
        }
        return new FunctionConfigUtils.ExtractedFunctionDetails(
                functionClassName,
                typeArgs[0].asErasure().getTypeName(),
                typeArgs[1].asErasure().getTypeName());
    }

    private static void doPythonChecks(FunctionConfig functionConfig) {
        if (functionConfig.getProcessingGuarantees() == FunctionConfig.ProcessingGuarantees.EFFECTIVELY_ONCE) {
            throw new RuntimeException("Effectively-once processing guarantees not yet supported in Python");
        }

        if (functionConfig.getWindowConfig() != null) {
            throw new IllegalArgumentException("There is currently no support windowing in python");
        }

        if (functionConfig.getMaxMessageRetries() != null && functionConfig.getMaxMessageRetries() >= 0) {
            throw new IllegalArgumentException("Message retries not yet supported in python");
        }
    }

    private static void doGolangChecks(FunctionConfig functionConfig) {
        if (functionConfig.getProcessingGuarantees() == FunctionConfig.ProcessingGuarantees.EFFECTIVELY_ONCE) {
            throw new RuntimeException("Effectively-once processing guarantees not yet supported in Go function");
        }

        if (functionConfig.getWindowConfig() != null) {
            throw new IllegalArgumentException("Windowing is not supported in Go function yet");

View on GitHub (pinned to 820761864e)

Solutions

  1. Use ATMOST_ONCE or ATLEAST_ONCE for Python functions
  2. Implement the function in Java if effectively-once is mandatory
  3. Add application-level deduplication with ATLEAST_ONCE as a workaround

Example fix

// before
config.setProcessingGuarantees(FunctionConfig.ProcessingGuarantees.EFFECTIVELY_ONCE); // python runtime
// after
config.setProcessingGuarantees(FunctionConfig.ProcessingGuarantees.ATLEAST_ONCE);
Defensive patterns

Strategy: validation

Validate before calling

if (config.getRuntime() == FunctionConfig.Runtime.PYTHON && config.getProcessingGuarantees() == FunctionConfig.ProcessingGuarantees.EFFECTIVELY_ONCE) { throw new IllegalArgumentException("EFFECTIVELY_ONCE is unsupported for Python functions"); }

Type guard

boolean pythonGuaranteeSupported(FunctionConfig c) { return c.getRuntime() != FunctionConfig.Runtime.PYTHON || c.getProcessingGuarantees() != FunctionConfig.ProcessingGuarantees.EFFECTIVELY_ONCE; }

Try / catch

try { ... } catch (RuntimeException e) { if (e.getMessage().contains("not yet supported in Python")) { log.error("Use ATLEAST_ONCE or implement in Java"); } }

Prevention

When it happens

Trigger: Submitting a function with runtime PYTHON and setProcessingGuarantees(EFFECTIVELY_ONCE), e.g. copying a Java function's config to a Python function.

Common situations: Teams standardizing on effectively-once for all functions; YAML configs shared between Java and Python functions without adjusting the guarantee.

Related errors


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/aed608ca9ff00603. Report an issue: GitHub.