{"record":{"id":"da6f8b1d48ff0fc4","repo":"apache/flink","slug":"jar-file-is-not-a-file","errorCode":null,"errorMessage":"JAR file is not a file: {}","messagePattern":"JAR file is not a file: (.+?)","errorType":"exception","errorClass":"FileNotFoundException","httpStatus":null,"severity":"error","filePath":"flink-clients/src/main/java/org/apache/flink/client/cli/CliFrontend.java","lineNumber":1072,"sourceCode":"                .setSavepointRestoreSettings(runOptions.getSavepointRestoreSettings())\n                .setArguments(programArgs)\n                .build();\n    }\n\n    /**\n     * Gets the JAR file from the path.\n     *\n     * @param jarFilePath The path of JAR file\n     * @return The JAR file\n     * @throws FileNotFoundException The JAR file does not exist.\n     */\n    private File getJarFile(String jarFilePath) throws FileNotFoundException {\n        File jarFile = new File(jarFilePath);\n        // Check if JAR file exists\n        if (!jarFile.exists()) {\n            throw new FileNotFoundException(\"JAR file does not exist: \" + jarFile);\n        } else if (!jarFile.isFile()) {\n            throw new FileNotFoundException(\"JAR file is not a file: \" + jarFile);\n        }\n        return jarFile;\n    }\n\n    // --------------------------------------------------------------------------------------------\n    //  Logging and Exception Handling\n    // --------------------------------------------------------------------------------------------\n\n    /**\n     * Displays an exception message for incorrect command line arguments.\n     *\n     * @param e The exception to display.\n     * @return The return code for the process.\n     */\n    private static int handleArgException(CliArgsException e) {\n        LOG.error(\"Invalid command line arguments.\", e);\n\n        System.out.println(e.getMessage());","sourceCodeStart":1054,"sourceCodeEnd":1090,"githubUrl":"https://github.com/apache/flink/blob/2f3c205e9266cb30240eb7f4fdab15cad629a70f/flink-clients/src/main/java/org/apache/flink/client/cli/CliFrontend.java#L1054-L1090","documentation":"Thrown from ParquetDataColumnReaderFactory's double-typed reader (DoubleBaseVector or DoubleDataFrameReader) when readTimestamp() is called on it — the DOUBLE reader implements every method of ParquetDataColumnReader but timestamps, which it hard-rejects. It signals the dispatch logic routed a timestamp read to a reader constructed for DOUBLE physical data, i.e. a physical-type/logical-type mismatch.","triggerScenarios":"A column declared TIMESTAMP in the Flink schema whose Parquet physical type is DOUBLE (writer stored epoch-millis/seconds as double); type-mapping tables in ParquetRowConverter ParquetDataColumnReaderFactory mapping a logical timestamp onto the double reader; inconsistent schemas after evolution.","commonSituations":"Reading files written by systems that store timestamps as floating-point epochs; schema evolution where a column changed type between writes; misconfigured Flink Parquet table schemas not matching the file's physical types.","solutions":["Check the Parquet physical type of the timestamp column (`parquet-tools schema`) and align the Flink schema to it (DOUBLE) or rewrite the file with INT64/millis timestamps","If the file legitimately stores epoch doubles, declare the column DOUBLE in Flink and cast to TIMESTAMP in SQL","Re-create the table/files so the timestamp annotation matches one of the supported physical mappings (INT64 with unit annotation, INT96)","Never mix schema versions where a column flips between DOUBLE and TIMESTAMP without rewriting the data"],"exampleFix":"-- before: file column is DOUBLE, schema says TIMESTAMP\nCREATE TABLE t (ts TIMESTAMP(3)) WITH ('format'='parquet', ...);\n\n-- after: read as DOUBLE, cast at query time\nCREATE TABLE t (ts_raw DOUBLE) WITH ('format'='parquet', ...);\nSELECT CAST(ts_raw * 1000 AS TIMESTAMP(3)) FROM t;","handlingStrategy":"type-guard","validationCode":"// Before reading, confirm the physical type backs the logical TIMESTAMP\nMessageType fileSchema = ParquetFileReader.readFooter(conf, path).getFileMetaData().getSchema();\nPrimitiveType pt = (PrimitiveType) fileSchema.getType(parquetColumnName);\nif (pt.getPrimitiveTypeName() == PrimitiveType.PrimitiveTypeName.DOUBLE) {\n    // map the column to DOUBLE in the Flink schema, not TIMESTAMP\n}","typeGuard":"static boolean physicalTypeSupportsTimestamp(PrimitiveType t) {\n    return t.getPrimitiveTypeName() == INT64\n        || t.getPrimitiveTypeName() == INT96;\n}","tryCatchPattern":"try {\n    vectorizedReader.readToVector(...);\n} catch (RuntimeException e) {\n    if (\"Unsupported operation\".equals(e.getMessage())\n            && ExceptionUtils.indexOfThrowable(e, RuntimeException.class) >= 0) {\n        // verify physical vs logical type alignment before proceeding\n    } else throw e;\n}","preventionTips":["Derive table DDL from the file schema (parquet-tools schema / hint derive) instead of hand-writing it","Standardize timestamp encoding (INT64 with isAdjustedToUTC + unit, or INT96) in writers","When schemas evolve across types, rewrite historical files rather than reinterpreting them"],"tags":["parquet","timestamp","type-mismatch","double"],"backgroundTag":null,"analyzedSha":"2f3c205e9266cb30240eb7f4fdab15cad629a70f","analyzedAt":"2026-08-14T08:48:24.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}