{"record":{"id":"e332584805146cdf","repo":"ipfs/kubo","slug":"mtime-nanoseconds-must-be-in-range-1-999999999","errorCode":null,"errorMessage":"mtime nanoseconds must be in range [1, 999999999]","messagePattern":"mtime nanoseconds must be in range \\[1, 999999999\\]","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/coreiface/options/unixfs.go","lineNumber":413,"sourceCode":"\treturn func(settings *UnixfsAddSettings) error {\n\t\tsettings.PreserveMtime = enable\n\t\treturn nil\n\t}\n}\n\n// Mode represents a unix file mode\nfunc (unixfsOpts) Mode(mode os.FileMode) UnixfsAddOption {\n\treturn func(settings *UnixfsAddSettings) error {\n\t\tsettings.Mode = mode\n\t\treturn nil\n\t}\n}\n\n// Mtime represents a unix file mtime\nfunc (unixfsOpts) Mtime(seconds int64, nsecs uint32) UnixfsAddOption {\n\treturn func(settings *UnixfsAddSettings) error {\n\t\tif nsecs > 999999999 {\n\t\t\treturn errors.New(\"mtime nanoseconds must be in range [1, 999999999]\")\n\t\t}\n\t\tsettings.Mtime = time.Unix(seconds, int64(nsecs))\n\t\treturn nil\n\t}\n}\n\n// IncludeEmptyDirs tells the adder to include empty directories in the DAG\nfunc (unixfsOpts) IncludeEmptyDirs(include bool) UnixfsAddOption {\n\treturn func(settings *UnixfsAddSettings) error {\n\t\tsettings.IncludeEmptyDirs = include\n\t\tsettings.IncludeEmptyDirsSet = true\n\t\treturn nil\n\t}\n}\n","sourceCodeStart":395,"sourceCodeEnd":428,"githubUrl":"https://github.com/ipfs/kubo/blob/329838acdfafae224582930457efe80aa217afc0/core/coreiface/options/unixfs.go#L395-L428","documentation":"Mtime sets a UnixFS timestamp (seconds plus nanoseconds, per the UnixFS spec's UnixTime metadata). The nanosecond sub-second field must be within [1, 999999999] (and is a uint32, so negatives are impossible); a larger value is meaningless in Go's time representation and is rejected.","triggerScenarios":"Calling options.Unixfs.Mtime(seconds, nsecs) with nsecs > 999999999 — e.g. Mtime(t.Unix(), t.Nanosecond()*1000) (mixing micro- and nanoseconds), or hardcoding 1000000000.","commonSituations":"Multiplying milliseconds or microseconds by the wrong factor (ms*1e6 vs µs*1e3) before passing; copying a full nanosecond-precision duration instead of its sub-second remainder; hand-rolled timestamp parsing producing out-of-range fractions.","solutions":["Pass the sub-second remainder as nanoseconds: time.Unix(sec, 0) then t.Nanosecond() (always < 1e9), not the raw t.UnixNano()","If your source is milliseconds, use nsecs = ms*1e6; for microseconds, use µs*1e3 — and verify the result stays under 1e9","If you only have second precision, pass 0 for nsecs"],"exampleFix":"// before\noptions.Unixfs.Mtime(t.Unix(), uint32(t.UnixNano())) // nsecs out of range\n\n// after\noptions.Unixfs.Mtime(t.Unix(), uint32(t.Nanosecond()))","handlingStrategy":"validation","validationCode":"func safeMtime(t time.Time) (int64, uint32, error) {\n    ns := t.Nanosecond() // always in [0, 999999999]\n    if ns < 0 {\n        return 0, 0, errors.New(\"negative nanoseconds\")\n    }\n    return t.Unix(), uint32(ns), nil\n}\nsec, nsec, err := safeMtime(t)\nif err != nil {\n    return err\n}\nopt := options.Unixfs.Mtime(sec, nsec)","typeGuard":"func nsecsInRange(n uint32) bool {\n    return n <= 999999999\n}","tryCatchPattern":"opt := options.Unixfs.Mtime(sec, nsec)\nif err := apply(opt); err != nil {\n    if strings.Contains(err.Error(), \"mtime nanoseconds\") {\n        // fall back to second precision\n        err = apply(options.Unixfs.Mtime(sec, 0))\n    }\n    if err != nil {\n        return err\n    }\n}","preventionTips":["Always derive nanoseconds from time.Time.Nanosecond(), never from time.Time.UnixNano()","Convert source units correctly: ms*1e6, µs*1e3, and verify < 1e9 before passing","If you only need second precision, pass nsecs = 0","Centralize timestamp conversion in one helper so the unit mistake happens in one auditable place"],"tags":["unixfs","mtime","validation","options"],"backgroundTag":"timestamp-nanoseconds-out-of-range","analyzedSha":"329838acdfafae224582930457efe80aa217afc0","analyzedAt":"2026-09-03T18:30:52.135Z","contentChangedAt":"2026-09-03T18:30:52.135Z","schemaVersion":2},"datasetVersion":"2026-09-11T00:17:11.886Z"}