keras-team/keras · error · ValueError

Expected `padding` to be a tuple of 3 tuples of 2 integers.

Error message

Expected `padding` to be a tuple of 3 tuples of 2 integers. Received: padding={padding}

What it means

Keras's legacy 3D spatial padding helper validates that `padding` is a nested structure of exactly 3 pairs, one (before, after) pair per spatial dimension of a 5D tensor (e.g. a 3D conv or 3D pooling op). Passing a flat tuple, a single int, the 2D-style ((1,1),(1,1)), or a ragged structure raises this ValueError before any op runs. The check exists because tf.pad needs an explicit per-dimension pad pattern that this helper builds from the argument.

Source

Thrown at keras/src/legacy/backend.py:2041

        raise ValueError(f"Unknown data_format: {data_format}")

    if data_format == "channels_first":
        pattern = [[0, 0], [0, 0], list(padding[0]), list(padding[1])]
    else:
        pattern = [[0, 0], list(padding[0]), list(padding[1]), [0, 0]]
    return tf.compat.v1.pad(x, pattern)


@keras_export("keras._legacy.backend.spatial_3d_padding")
def spatial_3d_padding(x, padding=((1, 1), (1, 1), (1, 1)), data_format=None):
    """DEPRECATED."""
    if (
        len(padding) != 3
        or len(padding[0]) != 2
        or len(padding[1]) != 2
        or len(padding[2]) != 2
    ):
        raise ValueError(
            "Expected `padding` to be a tuple of 3 tuples of 2 integers. "
            f"Received: padding={padding}"
        )
    if data_format is None:
        data_format = backend.image_data_format()
    if data_format not in {"channels_first", "channels_last"}:
        raise ValueError(f"Unknown data_format: {data_format}")

    if data_format == "channels_first":
        pattern = [
            [0, 0],
            [0, 0],
            [padding[0][0], padding[0][1]],
            [padding[1][0], padding[1][1]],
            [padding[2][0], padding[2][1]],
        ]
    else:
        pattern = [

View on GitHub (pinned to 7a34a03db6)

Solutions

  1. Pass padding as 3 pairs of ints, e.g. ((1,1),(2,2),(3,3)) — one pair per spatial dim of the 5D tensor
  2. If you meant 2D padding, call the 2D helper (spatial_2d_padding) or use ZeroPadding2D instead
  3. Validate config-file-derived padding shape with a guard before calling the legacy backend

Example fix

# before
spatial_3d_padding(x, padding=(1, 1))
# after
spatial_3d_padding(x, padding=((1, 1), (1, 1), (1, 1)))
Defensive patterns

Strategy: validation

Validate before calling

def valid_3d_padding(p):
    return (isinstance(p, (tuple, list)) and len(p) == 3
            and all(isinstance(d, (tuple, list)) and len(d) == 2
                    and all(isinstance(v, int) for v in d) for d in p))

padding = ((1, 1), (2, 2), (2, 2))
assert valid_3d_padding(padding), f'bad padding: {padding}'

Type guard

def is_3d_padding(p) -> bool:
    return (isinstance(p, tuple) and len(p) == 3
            and all(isinstance(d, tuple) and len(d) == 2 for d in p))

Prevention

When it happens

Trigger: Calling keras._legacy.backend.spatial_3d_padding(x, padding=...) with a flat tuple like (1,1,1), a 2-pair structure like ((1,1),(1,1)), a single integer, or any nested structure whose outer length is not 3 or whose elements are not length-2.

Common situations: Porting old Keras 2 code that mixed up 2D and 3D padding helpers; copying a Conv2D ZeroPadding2D config into a 3D pipeline; passing config-loaded padding flattened by YAML/JSON round-tripping.

Related errors


AI-assisted analysis of keras-team/keras@7a34a03db6 (2026-08-25). Data as JSON: /api/errors/155bb0da54db9081. Report an issue: GitHub.