{"record":{"id":"c7ee981a4cd06994","repo":"prestodb/presto","slug":"dictionary-is-missing-for-page","errorCode":null,"errorMessage":"Dictionary is missing for Page","messagePattern":"Dictionary is missing for Page","errorType":"exception","errorClass":"ParquetDecodingException","httpStatus":null,"severity":"error","filePath":"presto-parquet/src/main/java/com/facebook/presto/parquet/reader/AbstractColumnReader.java","lineNumber":338,"sourceCode":"        long firstRowIndex = page.getFirstRowIndex().orElse(-1L);\n        return initDataReader(page.getDataEncoding(), ByteBufferInputStream.wrap(ImmutableList.of(page.getSlice().toByteBuffer())), page.getValueCount(), firstRowIndex);\n    }\n\n    private LevelReader buildLevelRLEReader(int maxLevel, Slice slice)\n    {\n        if (maxLevel == 0) {\n            return new LevelNullReader();\n        }\n\n        return new LevelRLEReader(new RunLengthBitPackingHybridDecoder(BytesUtils.getWidthFromMaxInt(maxLevel), slice.getInput()));\n    }\n\n    private ValuesReader initDataReader(ParquetEncoding dataEncoding, ByteBufferInputStream inputStream, int valueCount, long firstRowIndex)\n    {\n        ValuesReader valuesReader;\n        if (dataEncoding.usesDictionary()) {\n            if (dictionary == null) {\n                throw new ParquetDecodingException(\"Dictionary is missing for Page\");\n            }\n            valuesReader = dataEncoding.getDictionaryBasedValuesReader(columnDescriptor, VALUES, dictionary);\n        }\n        else {\n            valuesReader = dataEncoding.getValuesReader(columnDescriptor, VALUES);\n        }\n\n        try {\n            valuesReader.initFromPage(valueCount, inputStream);\n            if (firstRowIndex != -1) {\n                currentRow = firstRowIndex - 1;\n            }\n            else {\n                currentRow = -1;\n            }\n            return valuesReader;\n        }\n        catch (IOException e) {","sourceCodeStart":320,"sourceCodeEnd":356,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-parquet/src/main/java/com/facebook/presto/parquet/reader/AbstractColumnReader.java#L320-L356","documentation":"initDataReader throws this when a page uses dictionary encoding (RLE_DICTIONARY / PLAIN_DICTIONARY) but the column reader's dictionary field is null — i.e. no dictionary page was supplied or decoded for this column chunk. A dictionary-encoded page cannot be decoded without its dictionary, so reading fails immediately.","triggerScenarios":"readPageV1/readPageV2 -> initDataReader with dataEncoding.usesDictionary() == true and dictionary == null, which happens when the dictionary page was absent from the chunk metadata stream (dropped/skipped), dictionary decoding previously failed leaving dictionary null, or the writer marked pages dictionary-encoded without emitting the dictionary page.","commonSituations":"Truncated files where the dictionary page was lost but data pages remain; files whose footer/dictionary metadata is inconsistent (writer bugs or third-party tools rewriting files incorrectly); reading partial column chunks from object storage with inconsistent reads; a preceding 'could not decode the dictionary' failure leaving dictionary null.","solutions":["Validate/re-copy the file; ensure the dictionary page for the column chunk is present and readable (parquet-tools dump).","Rewrite the file with dictionary encoding disabled so all data pages use plain encoding.","Re-export the data with a reliable writer if the file's dictionary metadata is inconsistent.","Upgrade Presto in case dictionary-page lookup/handling for that encoding is fixed in a newer version.","Check for earlier ParquetDecodingException logs for the same column — a failed initDictionary will leave dictionary null and surface as this error on the first data page."],"exampleFix":"// before\nSELECT col FROM broken_table;  -- ParquetDecodingException: Dictionary is missing for Page\n\n// after (rewrite without dictionary encoding)\n// $ parquet-tools rewrite bad.parquet fixed.parquet\nSELECT col FROM fixed_table;","handlingStrategy":"try-catch","validationCode":"// Verify dictionary pages exist for dictionary-encoded chunks before reading\n// $ parquet-tools dump file.parquet  # dictionary pages appear per column chunk","typeGuard":null,"tryCatchPattern":"try {\n    // scan column chunk\n}\ncatch (ParquetDecodingException e) {\n    if (e.getMessage().contains(\"Dictionary is missing for Page\")) {\n        logger.warn(\"Dictionary page missing; rewriting file without dictionary encoding\");\n        // fall back to a rewritten plain-encoded copy\n    } else {\n        throw e;\n    }\n}","preventionTips":["Check logs for earlier dictionary decode failures on the same column — they leave dictionary null.","Avoid reading column chunks through tools that drop dictionary pages when rewriting files.","Validate files with parquet-tools dump before registering them in tables.","Disable dictionary encoding at write time if your pipeline has a history of dictionary page issues."],"tags":["parquet","dictionary","decoding","missing-data"],"backgroundTag":"parquet-dictionary-missing","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"}