apache/flink · error · IndexOutOfBoundsException

Tuple position is out of range: {fieldPos}

Error message

Tuple position is out of range: {fieldPos}

What it means

Thrown by Keys.ExpressionKeys.isSortKey(int, TypeInformation) as an IndexOutOfBoundsException when the requested field position is negative or >= the tuple arity. This is an unchecked exception signalling an out-of-bounds index into the tuple schema.

Source

Thrown at flink-core/src/main/java/org/apache/flink/api/common/operators/Keys.java:454

        public String toString() {
            return "ExpressionKeys: " + StringUtils.join(keyFields, '.');
        }

        public static boolean isSortKey(int fieldPos, TypeInformation<?> type) {

            if (!type.isTupleType() || !(type instanceof CompositeType)) {
                throw new InvalidProgramException(
                        "Specifying keys via field positions is only valid "
                                + "for tuple data types. Type: "
                                + type);
            }
            if (type.getArity() == 0) {
                throw new InvalidProgramException(
                        "Tuple size must be greater than 0. Size: " + type.getArity());
            }

            if (fieldPos < 0 || fieldPos >= type.getArity()) {
                throw new IndexOutOfBoundsException("Tuple position is out of range: " + fieldPos);
            }

            TypeInformation<?> sortKeyType = ((CompositeType<?>) type).getTypeAt(fieldPos);
            return sortKeyType.isSortKeyType();
        }

        public static boolean isSortKey(String fieldExpr, TypeInformation<?> type) {

            TypeInformation<?> sortKeyType;

            fieldExpr = fieldExpr.trim();
            if (SELECT_ALL_CHAR.equals(fieldExpr) || SELECT_ALL_CHAR_SCALA.equals(fieldExpr)) {
                sortKeyType = type;
            } else {
                if (type instanceof CompositeType) {
                    sortKeyType = ((CompositeType<?>) type).getTypeAt(fieldExpr);
                } else {
                    throw new InvalidProgramException(

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Validate fieldPos against type.getArity() before calling the API.
  2. Use zero-based indexing and ensure fieldPos is in [0, arity-1].
  3. Switch to field-name-based access if positions are error-prone.

Example fix

// before
int pos = 5;
Keys.ExpressionKeys.isSortKey(pos, tupleTypeInfo);  // Tuple3 → out of range

// after
int pos = 5;
if (pos < 0 || pos >= tupleTypeInfo.getArity()) {
    throw new IllegalArgumentException("pos " + pos + " out of range");
}
Keys.ExpressionKeys.isSortKey(pos, tupleTypeInfo);
Defensive patterns

Strategy: validation

Validate before calling

if (fieldPos < 0 || fieldPos >= type.getArity()) {
    throw new IllegalArgumentException(
        "Field position " + fieldPos + " out of range [0,"
            + (type.getArity() - 1) + "]");
}

Try / catch

try {
    Keys.ExpressionKeys.isSortKey(pos, type);
} catch (IndexOutOfBoundsException e) {
    throw new IllegalArgumentException("Invalid sort position " + pos, e);
}

Prevention

When it happens

Trigger: Calling isSortKey(5, type) on a Tuple3 (arity 3), or passing a negative position. Any positional keyBy/sort API that forwards an unchecked index.

Common situations: Off-by-one errors when computing key positions programmatically. Assuming a tuple has more fields than it does after a schema change.

Related errors


AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14). Data as JSON: /api/errors/b9c71ab2e5c05be8. Report an issue: GitHub.