Unity-Technologies/ml-agents · error · RuntimeError

The {source} provided had NaN values.

Error message

The {source} provided had NaN values.

What it means

RuntimeError raised by _raise_on_nan_and_inf when the mean of the data being processed (observation, reward, etc. from Unity) is NaN, indicating the environment sent non-numeric values. The library fails fast because NaNs would silently poison training.

Source

Thrown at ml-agents-envs/mlagents_envs/rpc_utils.py:286

    return np.array(batched_visual, dtype=np.float32)


def _raise_on_nan_and_inf(data: np.array, source: str) -> np.array:
    # Check for NaNs or Infinite values in the observation or reward data.
    # If there's a NaN in the observations, the np.mean() result will be NaN
    # If there's an Infinite value (either sign) then the result will be Inf
    # See https://stackoverflow.com/questions/6736590/fast-check-for-nan-in-numpy for background
    # Note that a very large values (larger than sqrt(float_max)) will result in an Inf value here
    # Raise a Runtime error in the case that NaNs or Infinite values make it into the data.
    if data.size == 0:
        return data

    d = np.mean(data)
    has_nan = np.isnan(d)
    has_inf = not np.isfinite(d)

    if has_nan:
        raise RuntimeError(f"The {source} provided had NaN values.")
    if has_inf:
        raise RuntimeError(f"The {source} provided had Infinite values.")


@timed
def _process_rank_one_or_two_observation(
    obs_index: int,
    observation_spec: ObservationSpec,
    agent_info_list: Collection[AgentInfoProto],
) -> np.ndarray:
    if len(agent_info_list) == 0:
        return np.zeros((0,) + observation_spec.shape, dtype=np.float32)
    try:
        np_obs = np.array(
            [
                agent_obs.observations[obs_index].float_data.data
                for agent_obs in agent_info_list
            ],

View on GitHub (pinned to 3ecb446f75)

Solutions

  1. Inspect the Unity environment for unstable simulation (limit rigidbody velocities, clamp torques, use fixed timesteps) and fix NaN-producing sensors/rewards.
  2. Use env.reset() to restart the episode and check if NaNs recur immediately or only after long rollouts.
  3. Clamp observations/rewards Unity-side or in a wrapper before they reach the trainer.
  4. Update com.unity.ml-agents and mlagents-envs to matching latest versions in case of a known serialization bug.

Example fix

// before
# Unity reward: reward = 1 / distance_to_target  -> inf/NaN when distance == 0
// after
# Unity C#: reward = distance_to_target > 1e-6 ? 1f / distance_to_target : 0f;
Defensive patterns

Strategy: try-catch

Validate before calling

import numpy as np

def obs_clean(arr: np.ndarray) -> bool:
    return np.isfinite(arr).all()

Type guard

import numpy as np

def has_no_nan(arr: np.ndarray) -> bool:
    return not np.isnan(arr).any()

Try / catch

from mlagents_envs.exception import UnityException
import numpy as np

try:
    env.step()
except RuntimeError as e:
    if "had NaN values" in str(e):
        decision_steps, terminal_steps = env.reset()  # restart episode

Prevention

When it happens

Trigger: steps_from_proto or _process_rank_one_or_two_observation receiving data containing NaN — e.g. agent state diverged, sensor producing NaN in Unity, physics instability, or reward function dividing by zero.

Common situations: Unstable physics simulations (fast rotations, extreme forces) in Unity producing NaN transforms; custom sensors or reward functions with division by zero; uninitialized textures/cameras in the environment; corrupted observation floats.

Related errors


AI-assisted analysis of Unity-Technologies/ml-agents@3ecb446f75 (2026-09-02). Data as JSON: /api/errors/32b5109511d34555. Report an issue: GitHub.