prestodb/presto · error · IllegalArgumentException

nanos field of an encoded timestamp in ORC must be between 0

Error message

nanos field of an encoded timestamp in ORC must be between 0 and 999999999 inclusive, got 

What it means

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.

Source

Thrown at presto-orc/src/main/java/com/facebook/presto/orc/reader/ApacheHiveTimestampDecoder.java:30

 * limitations under the License.
 */
package com.facebook.presto.orc.reader;

import com.facebook.presto.orc.DecodeTimestampOptions;

final class ApacheHiveTimestampDecoder
{
    private ApacheHiveTimestampDecoder() {}

    // This comes from the Apache Hive ORC code
    public static long decodeTimestamp(long seconds, long serializedNanos, DecodeTimestampOptions options)
    {
        boolean enableMicroPrecision = options.enableMicroPrecision();
        long secondsWithBase = seconds + options.getBaseSeconds();
        long value = getSecondsInRequiredUnits(enableMicroPrecision, secondsWithBase, options.getUnitsPerSecond());
        long nanos = parseNanos(serializedNanos);
        if (nanos > 999999999 || nanos < 0) {
            throw new IllegalArgumentException("nanos field of an encoded timestamp in ORC must be between 0 and 999999999 inclusive, got " + nanos);
        }

        // the rounding error exists because java always rounds up when dividing integers
        // -42001/1000 = -42; and -42001 % 1000 = -1 (+ 1000)
        // to get the correct value we need
        // (-42 - 1)*1000 + 999 = -42001
        // (42)*1000 + 1 = 42001
        if (value < 0 && nanos != 0) {
            value -= options.getUnitsPerSecond();
        }
        // Truncate nanos to required units (millis / micros)
        long truncatedNanos = nanos / options.getNanosPerUnit();
        return getValueWithNanos(enableMicroPrecision, value, truncatedNanos);
    }

    private static long getSecondsInRequiredUnits(boolean enableMicroPrecision, long secondsWithBase, long unitsPerSecond)
    {
        if (!enableMicroPrecision) {

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Verify the ORC file is not corrupted; rewrite the file with a trusted writer (e.g. current Hive or Presto itself).
  2. Check the writer version/tool that produced the ORC file for known timestamp encoding bugs and upgrade it.
  3. Confirm nanosOfSecond encoding settings in the writer are standard (max nano precision not misconfigured).
  4. Validate the file with an ORC metadata/scan tool (orc-tools) to locate the corrupt stripe.

Example fix

// before: reading suspect file directly
Cursor cursor = reader.read();
// after: validate file first with orc-tools, then rewrite
// hive --orcfiledump bad.orc  -> find corrupt stripe
// rewrite: INSERT INTO clean_table SELECT ... FROM bad_table;
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-validate ORC file timestamps before query
// orc-tools scan file.orc  -- check TIMESTAMP columns decode cleanly

Type guard

boolean isValidNanos(long nanos) { return nanos >= 0 && nanos <= 999999999; }

Try / catch

try { ts = decoder.decodeTimestamp(...); } catch (IllegalArgumentException e) { log.error("corrupt ORC timestamp nanos", e); ts = null; }

Prevention

When it happens

Trigger: 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().

Common situations: 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.

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/f7ff24f1241456b9. Report an issue: GitHub.