{"record":{"id":"f2e7a523c26b70eb","repo":"JamesNK/Newtonsoft.Json","slug":"cannot-convert-date-value-that-is-before-unix-epoc","errorCode":null,"errorMessage":"Cannot convert date value that is before Unix epoch of 00:00:00 UTC on 1 January 1970.","messagePattern":"Cannot convert date value that is before Unix epoch of 00:00:00 UTC on 1 January 1970\\.","errorType":"exception","errorClass":"JsonSerializationException","httpStatus":null,"severity":"error","filePath":"Src/Newtonsoft.Json/Converters/UnixDateTimeConverter.cs","lineNumber":97,"sourceCode":"\n            if (value is DateTime dateTime)\n            {\n                seconds = (long)(dateTime.ToUniversalTime() - UnixEpoch).TotalSeconds;\n            }\n#if HAVE_DATE_TIME_OFFSET\n            else if (value is DateTimeOffset dateTimeOffset)\n            {\n                seconds = (long)(dateTimeOffset.ToUniversalTime() - UnixEpoch).TotalSeconds;\n            }\n#endif\n            else\n            {\n                throw new JsonSerializationException(\"Expected date object value.\");\n            }\n\n            if (!AllowPreEpoch && seconds < 0)\n            {\n                throw new JsonSerializationException(\"Cannot convert date value that is before Unix epoch of 00:00:00 UTC on 1 January 1970.\");\n            }\n\n            writer.WriteValue(seconds);\n        }\n\n        /// <summary>\n        /// Reads the JSON representation of the object.\n        /// </summary>\n        /// <param name=\"reader\">The <see cref=\"JsonReader\"/> to read from.</param>\n        /// <param name=\"objectType\">Type of the object.</param>\n        /// <param name=\"existingValue\">The existing property value of the JSON that is being converted.</param>\n        /// <param name=\"serializer\">The calling serializer.</param>\n        /// <returns>The object value.</returns>\n        public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)\n        {\n            bool nullable = ReflectionUtils.IsNullable(objectType);\n            if (reader.TokenType == JsonToken.Null)\n            {","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/JamesNK/Newtonsoft.Json/blob/4f73e74372445108d2c1bda37b36e6f5e43402e0/Src/Newtonsoft.Json/Converters/UnixDateTimeConverter.cs#L79-L115","documentation":"Thrown by UnixDateTimeConverter.WriteJson when the DateTime/DateTimeOffset, converted to UTC and expressed as seconds since the Unix epoch, is negative and AllowPreEpoch is false (the default). The Unix epoch is 00:00:00 UTC on 1 January 1970; dates before that yield negative seconds and are rejected unless explicitly allowed.","triggerScenarios":"Serializing a DateTime or DateTimeOffset earlier than 1970-01-01T00:00:00Z with UnixDateTimeConverter whose AllowPreEpoch property is false (default). Any birthdate, historical date, or log timestamp before 1970 trips it.","commonSituations":"Birth dates, historical records, or legacy timestamps before 1970 serialized as Unix seconds. Defaulting AllowPreEpoch to false and forgetting to enable it for data that legitimately predates the epoch.","solutions":["Set UnixDateTimeConverter.AllowPreEpoch = true to permit pre-1970 dates.","If your consumer cannot handle negative epoch values, switch to IsoDateTimeConverter for pre-epoch data.","Sanitize/clamp dates to the epoch boundary only if pre-epoch values are truly invalid for your domain."],"exampleFix":"// before: default converter rejects pre-epoch dates\nvar conv = new UnixDateTimeConverter();\nsettings.Converters.Add(conv);\nJsonConvert.SerializeObject(new { Dob = new DateTime(1960,1,1) }, settings);\n\n// after: allow pre-epoch\nvar conv = new UnixDateTimeConverter { AllowPreEpoch = true };\nsettings.Converters.Add(conv);","handlingStrategy":"validation","validationCode":"DateTime value = GetValue();\nif (value < new DateTime(1970,1,1) && !converter.AllowPreEpoch)\n    throw new ArgumentOutOfRangeException(nameof(value), \"Date is before Unix epoch; set AllowPreEpoch=true or use IsoDateTimeConverter\");","typeGuard":"static bool IsPostEpoch(DateTime d) => d >= new DateTime(1970, 1, 1);","tryCatchPattern":"try { conv.WriteJson(writer, value, serializer); }\ncatch (JsonSerializationException ex) when (ex.Message.Contains(\"before Unix epoch\"))\n{\n    throw new ArgumentOutOfRangeException(\"Date predates the Unix epoch; enable AllowPreEpoch\", ex);\n}","preventionTips":["Set AllowPreEpoch = true when serializing dates that may predate 1970 (birth dates, history).","For mixed-era data, consider IsoDateTimeConverter to avoid the epoch boundary entirely.","Validate date ranges before serialization to surface domain errors early."],"tags":["serialization","converter","datetime","unix-time","validation"],"analyzedSha":"4f73e74372445108d2c1bda37b36e6f5e43402e0","analyzedAt":"2026-08-07T06:10:08.596Z","schemaVersion":2},"datasetVersion":"2026-08-07T07:17:06.508Z"}