XINCGer/Unity3DTraining · error · InvalidOperationException

Timestamp contains invalid values: Seconds=

Error message

Timestamp contains invalid values: Seconds={Seconds}; Nanos={Nanos}

What it means

Timestamp.ToDateTime requires the timestamp to be normalized (Nanos in [0, 999999999]) and within the valid DateTime range (0001-01-01 to 9999-12-31 after conversion from Unix epoch). IsNormalized checks both; when it fails the method throws InvalidOperationException describing the offending Seconds/Nanos. Converting an out-of-range or non-normalized timestamp to a DateTime is impossible without overflow.

Solutions

  1. Check Timestamp.IsNormalized-equivalent before converting: validate Nanos >= 0 && Nanos < 1_000_000_000 and Seconds within DateTime-representable range
  2. Fix the producer so it normalizes (borrow from Seconds when Nanos is negative)
  3. If you need range beyond DateTime, use ToDateTimeOffset on a DateTimeOffset-capable path or keep the raw Seconds/Nanos
  4. Clamp or reject out-of-range timestamps at deserialization boundaries

Example fix

// before
var ts = new Timestamp { Seconds = -7_000_000_000L, Nanos = -5 };
var dt = ts.ToDateTime(); // throws
// after
if (ts.Nanos < 0 || ts.Nanos > 999_999_999)
{
    // repair or reject
    ts = new Timestamp { Seconds = ts.Seconds - 1, Nanos = ts.Nanos + 1_000_000_000 };
}
var dt2 = ts.ToDateTime();
Defensive patterns

Strategy: validation

Validate before calling

static bool IsConvertibleTimestamp(Timestamp t) => t.Nanos >= 0 && t.Nanos < 1_000_000_000 && t.Seconds >= -62135596800L && t.Seconds <= 253402300799L;

Type guard

static bool IsSafeTimestamp(Timestamp t) => t != null && t.Nanos >= 0 && t.Nanos < 1_000_000_000;

Try / catch

try { return ts.ToDateTime(); } catch (InvalidOperationException ex) { log.Warn(ex, "Invalid timestamp {Seconds}/{Nanos}", ts.Seconds, ts.Nanos); return DateTime.MinValue; }

Prevention

When it happens

Trigger: Calling ToDateTime() (directly or via ToDateTimeOffset) on a Timestamp with negative Nanos, Nanos >= 1e9, or Seconds outside the range that maps into DateTime's min/max (roughly seconds -62135596800..253402300799).

Common situations: Timestamps decoded from untrusted or buggy producers (e.g. nanos populated with milliseconds * 1e6 overflow); sentinel values like Seconds=0/Nanos=-1; very large Seconds from int64 overflow upstream; timestamps pre-1AD or post-9999AD.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of XINCGer/Unity3DTraining@016f98412e (2026-09-12). Data as JSON: /api/errors/14efbf41d3f0db09. Report an issue: GitHub.

Appendix: source

Thrown at NetWorkAndResources/Socket_Protobuff/Assets/Plugins/Google.Protobuf/WellKnownTypes/TimestampPartial.cs:120

        }

        /// <summary>
        /// Converts this timestamp into a <see cref="DateTime"/>.
        /// </summary>
        /// <remarks>
        /// The resulting <c>DateTime</c> will always have a <c>Kind</c> of <c>Utc</c>.
        /// If the timestamp is not a precise number of ticks, it will be truncated towards the start
        /// of time. For example, a timestamp with a <see cref="Nanos"/> value of 99 will result in a
        /// <see cref="DateTime"/> value precisely on a second.
        /// </remarks>
        /// <returns>This timestamp as a <c>DateTime</c>.</returns>
        /// <exception cref="InvalidOperationException">The timestamp contains invalid values; either it is
        /// incorrectly normalized or is outside the valid range.</exception>
        public DateTime ToDateTime()
        {
            if (!IsNormalized(Seconds, Nanos))
            {
                throw new InvalidOperationException(@"Timestamp contains invalid values: Seconds={Seconds}; Nanos={Nanos}");
            }
            return UnixEpoch.AddSeconds(Seconds).AddTicks(Nanos / Duration.NanosecondsPerTick);
        }

        /// <summary>
        /// Converts this timestamp into a <see cref="DateTimeOffset"/>.
        /// </summary>
        /// <remarks>
        /// The resulting <c>DateTimeOffset</c> will always have an <c>Offset</c> of zero.
        /// If the timestamp is not a precise number of ticks, it will be truncated towards the start
        /// of time. For example, a timestamp with a <see cref="Nanos"/> value of 99 will result in a
        /// <see cref="DateTimeOffset"/> value precisely on a second.
        /// </remarks>
        /// <returns>This timestamp as a <c>DateTimeOffset</c>.</returns>
        /// <exception cref="InvalidOperationException">The timestamp contains invalid values; either it is
        /// incorrectly normalized or is outside the valid range.</exception>
        public DateTimeOffset ToDateTimeOffset()
        {

View on GitHub (pinned to 016f98412e)