alibaba/DataX · error · RuntimeException
TRANSFORMER_RUN_EXCEPTION
TRANSFORMER_RUN_EXCEPTION
Error message
dx_substr startIndex(%s) out of range(%s)
What it means
Thrown by dx_substr when startIndex is greater than the length of the column's string value, since substring cannot start past the end. The check is per record after column.asString() (null values skip processing), so it fires only on rows whose value is shorter than startIndex, wrapped as TRANSFORMER_RUN_EXCEPTION.
Source
Thrown at core/src/main/java/com/alibaba/datax/core/transport/transformer/SubstrTransformer.java:50
columnIndex = (Integer) paras[0];
startIndex = Integer.valueOf((String) paras[1]);
length = Integer.valueOf((String) paras[2]);
} catch (Exception e) {
throw DataXException.asDataXException(TransformerErrorCode.TRANSFORMER_ILLEGAL_PARAMETER, "paras:" + Arrays.asList(paras).toString() + " => " + e.getMessage());
}
Column column = record.getColumn(columnIndex);
try {
String oriValue = column.asString();
//如果字段为空,跳过subStr处理
if(oriValue == null){
return record;
}
String newValue;
if (startIndex > oriValue.length()) {
throw new RuntimeException(String.format("dx_substr startIndex(%s) out of range(%s)", startIndex, oriValue.length()));
}
if (startIndex + length >= oriValue.length()) {
newValue = oriValue.substring(startIndex, oriValue.length());
} else {
newValue = oriValue.substring(startIndex, startIndex + length);
}
record.setColumn(columnIndex, new StringColumn(newValue));
} catch (Exception e) {
throw DataXException.asDataXException(TransformerErrorCode.TRANSFORMER_RUN_EXCEPTION, e.getMessage(),e);
}
return record;
}
}
View on GitHub (pinned to 80ec23d5c5)
Solutions
- Reduce startIndex to be <= the minimum non-null string length observed in the column.
- Chain dx_pad before dx_substr to guarantee a minimum length, or use startIndex 0 when the intent is 'from the beginning'.
- Find the offending row in the DataX task log (record contents are printed with the error) and validate the parameter against real data.
Example fix
// before: value "abc", startIndex 4 "paras": [1, "4", "2"] // after "paras": [1, "0", "2"]
Defensive patterns
Strategy: validation
Validate before calling
String v = record.getColumn(idx).asString(); if (v != null && startIndex > v.length()) startIndex = 0; // or clamp to v.length() for empty result
Try / catch
catch DataXException(TRANSFORMER_RUN_EXCEPTION): quarantine the record with its raw value for later repair instead of failing the channel.
Prevention
- Verify MIN(string length) >= startIndex on production data, not samples.
- Prefer startIndex 0 + length when the intent is a fixed prefix extraction.
When it happens
Trigger: A row where the target column holds a string shorter than startIndex, e.g. startIndex=4 against "abc". startIndex == length is tolerated (yields empty string); only strictly greater throws.
Common situations: Source data whose column widths vary (free-text fields, codes of differing lengths), a startIndex tuned to one schema and reused against another, or trailing-whitespace trimming upstream that shortens values unexpectedly.
Related errors
- TRANSFORMER_RUN_EXCEPTION
- TRANSFORMER_ILLEGAL_PARAMETER
- dx_digest paras length must be 3
- dx_digest paras index 1 must be md5 or sha1
- dx_digest paras index 2 must be toUpperCase or toLowerCase
AI-assisted analysis of alibaba/DataX@80ec23d5c5 (2026-08-14).
Data as JSON: /api/errors/21c6ef0abb0c239e.
Report an issue: GitHub.