keras-team/keras · error · ValueError

All `axis` values to be kept must have a known shape. Receiv

Error message

All `axis` values to be kept must have a known shape. Received axis={self.axis}, inputs.shape={input_shape}, with unknown axis at index {d}

What it means

Normalization must know the size of every kept axis to size its mean/variance buffers. build() raises when input_shape[d] is None for any kept axis d — i.e. that dimension is dynamic/unknown.

Source

Thrown at keras/src/layers/preprocessing/normalization.py:175

        ndim = len(input_shape)
        self._build_input_shape = input_shape

        if any(a < -ndim or a >= ndim for a in self.axis):
            raise ValueError(
                "All `axis` values must be in the range [-ndim, ndim). "
                f"Received inputs with ndim={ndim}, while axis={self.axis}"
            )

        # Axes to be kept, replacing negative values with positive equivalents.
        # Sorted to avoid transposing axes.
        self._keep_axis = tuple(
            sorted([d if d >= 0 else d + ndim for d in self.axis])
        )
        # All axes to be kept should have known shape.
        for d in self._keep_axis:
            if input_shape[d] is None:
                raise ValueError(
                    "All `axis` values to be kept must have a known shape. "
                    f"Received axis={self.axis}, "
                    f"inputs.shape={input_shape}, "
                    f"with unknown axis at index {d}"
                )
        # Axes to be reduced.
        self._reduce_axis = tuple(
            d for d in range(ndim) if d not in self._keep_axis
        )
        # 1 if an axis should be reduced, 0 otherwise.
        self._reduce_axis_mask = [
            0 if d in self._keep_axis else 1 for d in range(ndim)
        ]
        # Broadcast any reduced axes.
        self._broadcast_shape = [
            input_shape[d] if d in self._keep_axis else 1 for d in range(ndim)
        ]
        mean_and_var_shape = tuple(input_shape[d] for d in self._keep_axis)

View on GitHub (pinned to 7a34a03db6)

Solutions

  1. Specify a concrete feature dimension in the input, e.g. keras.Input(shape=(max_len, n_features))
  2. Normalize an axis whose size is known
  3. Pad or truncate inputs so the kept axis has a static size

Example fix

// before
inputs = keras.Input(shape=(None,))  # unknown last dim
norm = Normalization(axis=-1)(inputs)
// after
inputs = keras.Input(shape=(256,))
norm = Normalization(axis=-1)(inputs)
Defensive patterns

Strategy: validation

Validate before calling

for d in [d if d >= 0 else d + ndim for d in axis_list]:
    assert input_shape[d] is not None, f'axis {d} must have a static size'

Prevention

When it happens

Trigger: Feeding symbolic tensors with an unknown feature dimension, e.g. input shape (None, None), into Normalization(axis=-1); functional models built from TensorSpec(shape=[None,None]).

Common situations: Variable-length inputs without a fixed feature width; converting eager code to a graph where the last dim was implicit.

Related errors


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