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
- Check Timestamp.IsNormalized-equivalent before converting: validate Nanos >= 0 && Nanos < 1_000_000_000 and Seconds within DateTime-representable range
- Fix the producer so it normalizes (borrow from Seconds when Nanos is negative)
- If you need range beyond DateTime, use ToDateTimeOffset on a DateTimeOffset-capable path or keep the raw Seconds/Nanos
- 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
- Check the exception message's Seconds/Nanos to find the faulty producer
- Reject or clamp timestamps at the ingestion boundary
- Prefer DateTimeOffset arithmetic for extreme ranges
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
- Conversion from DateTime to Timestamp requires the DateTime…
- Non-normalized timestamp value
- Expected string value for Timestamp
- Invalid Timestamp value
- Non-normalized duration value
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)