apache/beam · critical · java.lang.RuntimeException
Unable to convert pipeline options, please check for…
Error message
Unable to convert pipeline options, please check for outdated jackson-core version in the classpath.
What it means
PipelineOptionsTranslation.toProto serializes PipelineOptions to JSON with Jackson and requires the resulting object to have at least one 'options' entry; mandatory options make an empty map impossible when Jackson works correctly. An empty fields() iterator indicates an incompatible/outdated jackson-core (observed with 2.2.3) silently producing wrong output, so Beam fails fast with this RuntimeException.
Solutions
- Run 'mvn dependency:tree' (or Gradle dependencies) and force jackson-core to the Beam-managed version, excluding stale transitive versions
- Check the runtime classpath/jar for duplicate jackson-core jars and remove outdated ones
- Add an explicit jackson-core dependency pinned to the Beam BOM version
Example fix
// before (pom.xml) <dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-core</artifactId><version>2.2.3</version></dependency> // after <dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-core</artifactId><version>2.16.1</version></dependency>
Defensive patterns
Strategy: validation
Validate before calling
String version = com.fasterxml.jackson.core.json.PackageVersion.VERSION.toString();
if (version.compareTo("2.14") < 0) throw new IllegalStateException("jackson-core too old: " + version); Try / catch
try { Struct s = PipelineOptionsTranslation.toProto(options); } catch (RuntimeException e) { if (e.getMessage().contains("jackson-core")) throw new IllegalStateException("Fix jackson-core version on classpath", e); throw e; } Prevention
- Run dependency:tree and check for old transitive jackson-core
- Shade/exclude duplicate Jackson artifacts in fat jars
- Pin jackson-core to the Beam BOM version
When it happens
Trigger: Calling PipelineOptionsTranslation.toProto/toJson when the classpath contains an old jackson-core (e.g. 2.2.3) that mis-serializes the options object into an empty root.
Common situations: Dependency conflicts pulling an ancient jackson-core transitively; fat jars bundling multiple Jackson versions; shaded/classloader environments resolving the wrong Jackson class.
Understand the failure class
Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.
Related errors
- AutoValue generated class not found
- Class ' ' does not implement PipelineRunner. Supported…
- Failed to convert PipelineOptions to Protocol
- Failed to load user-provided jar(s).
- Failed to locate DefaultGetSize.validateSize()
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/ef078db4dfe5d056.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/util/construction/PipelineOptionsTranslation.java:63
public static final String PIPELINE_OPTIONS_URN_PREFIX = "beam:option:";
public static final String PIPELINE_OPTIONS_URN_SUFFIX = ":v1";
/** Converts the provided {@link PipelineOptions} to a {@link Struct}. */
public static Struct toProto(PipelineOptions options) {
Struct.Builder builder = Struct.newBuilder();
try {
// TODO: Officially define URNs for options and their scheme.
JsonNode treeNode = MAPPER.valueToTree(options);
JsonNode rootOptions = treeNode.get("options");
Iterator<Map.Entry<String, JsonNode>> optionsEntries = rootOptions.fields();
if (!optionsEntries.hasNext()) {
// Due to mandatory options there is no way this map can be empty.
// If it is, then fail fast as it is due to incompatible jackson-core in the classpath.
// (observed with version 2.2.3)
throw new RuntimeException(
"Unable to convert pipeline options, please check for outdated jackson-core version in the classpath.");
}
Map<String, TreeNode> optionsUsingUrns = new HashMap<>();
while (optionsEntries.hasNext()) {
Map.Entry<String, JsonNode> entry = optionsEntries.next();
optionsUsingUrns.put(
PIPELINE_OPTIONS_URN_PREFIX
+ CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, entry.getKey())
+ PIPELINE_OPTIONS_URN_SUFFIX,
entry.getValue());
}
// The JSON format of a Protobuf Struct is the JSON object that is equivalent to that struct
// (with values encoded in a standard json-codeable manner). See Beam PR 3719 for more.
JsonFormat.parser().merge(MAPPER.writeValueAsString(optionsUsingUrns), builder);
return builder.build();
} catch (IOException e) {View on GitHub (pinned to 12126d8942)