{"record":{"id":"f7ff24f1241456b9","repo":"prestodb/presto","slug":"nanos-field-of-an-encoded-timestamp-in-orc-must-be","errorCode":null,"errorMessage":"nanos field of an encoded timestamp in ORC must be between 0 and 999999999 inclusive, got ","messagePattern":"nanos field of an encoded timestamp in ORC must be between 0 and 999999999 inclusive, got ","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"presto-orc/src/main/java/com/facebook/presto/orc/reader/ApacheHiveTimestampDecoder.java","lineNumber":30,"sourceCode":" * limitations under the License.\n */\npackage com.facebook.presto.orc.reader;\n\nimport com.facebook.presto.orc.DecodeTimestampOptions;\n\nfinal class ApacheHiveTimestampDecoder\n{\n    private ApacheHiveTimestampDecoder() {}\n\n    // This comes from the Apache Hive ORC code\n    public static long decodeTimestamp(long seconds, long serializedNanos, DecodeTimestampOptions options)\n    {\n        boolean enableMicroPrecision = options.enableMicroPrecision();\n        long secondsWithBase = seconds + options.getBaseSeconds();\n        long value = getSecondsInRequiredUnits(enableMicroPrecision, secondsWithBase, options.getUnitsPerSecond());\n        long nanos = parseNanos(serializedNanos);\n        if (nanos > 999999999 || nanos < 0) {\n            throw new IllegalArgumentException(\"nanos field of an encoded timestamp in ORC must be between 0 and 999999999 inclusive, got \" + nanos);\n        }\n\n        // the rounding error exists because java always rounds up when dividing integers\n        // -42001/1000 = -42; and -42001 % 1000 = -1 (+ 1000)\n        // to get the correct value we need\n        // (-42 - 1)*1000 + 999 = -42001\n        // (42)*1000 + 1 = 42001\n        if (value < 0 && nanos != 0) {\n            value -= options.getUnitsPerSecond();\n        }\n        // Truncate nanos to required units (millis / micros)\n        long truncatedNanos = nanos / options.getNanosPerUnit();\n        return getValueWithNanos(enableMicroPrecision, value, truncatedNanos);\n    }\n\n    private static long getSecondsInRequiredUnits(boolean enableMicroPrecision, long secondsWithBase, long unitsPerSecond)\n    {\n        if (!enableMicroPrecision) {","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-orc/src/main/java/com/facebook/presto/orc/reader/ApacheHiveTimestampDecoder.java#L12-L48","documentation":"This IllegalArgumentException is thrown by ApacheHiveTimestampDecoder.decodeTimestamp when a TIMESTAMP value read from an ORC file carries a nanos component outside the valid 0..999999999 range. ORC encodes nanos-of-second as a non-negative value below one second, so an out-of-range value means the encoded data is malformed or decoded incorrectly. It guards Presto's internal timestamp arithmetic from a corrupt nanos field.","triggerScenarios":"Reading an ORC TIMESTAMP column whose serialized nanos field, after parseNanos decoding, is negative or greater than 999999999 — i.e. decoding a corrupt or non-standard ORC file with decodeTimestamp().","commonSituations":"Files written by buggy or third-party ORC writers that encode nanos incorrectly; files corrupted in transit/storage; reading files produced by incompatible Hive/ORC versions with divergent timestamp encodings.","solutions":["Verify the ORC file is not corrupted; rewrite the file with a trusted writer (e.g. current Hive or Presto itself).","Check the writer version/tool that produced the ORC file for known timestamp encoding bugs and upgrade it.","Confirm nanosOfSecond encoding settings in the writer are standard (max nano precision not misconfigured).","Validate the file with an ORC metadata/scan tool (orc-tools) to locate the corrupt stripe."],"exampleFix":"// before: reading suspect file directly\nCursor cursor = reader.read();\n// after: validate file first with orc-tools, then rewrite\n// hive --orcfiledump bad.orc  -> find corrupt stripe\n// rewrite: INSERT INTO clean_table SELECT ... FROM bad_table;","handlingStrategy":"try-catch","validationCode":"// pre-validate ORC file timestamps before query\n// orc-tools scan file.orc  -- check TIMESTAMP columns decode cleanly","typeGuard":"boolean isValidNanos(long nanos) { return nanos >= 0 && nanos <= 999999999; }","tryCatchPattern":"try { ts = decoder.decodeTimestamp(...); } catch (IllegalArgumentException e) { log.error(\"corrupt ORC timestamp nanos\", e); ts = null; }","preventionTips":["Write ORC files only with well-known, up-to-date writers","Validate files with orc-tools before loading into Presto","Avoid hand-rolled ORC writers for timestamp columns","Checksum files on transfer to detect corruption"],"tags":["orc","timestamp","data-corruption","presto"],"backgroundTag":"corrupt-orc-timestamp-nanos","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}