When querying Iceberg tables registered in AWS Glue that contain timestamp columns, ClickHouse fails with:
Received exception from server (version 25.11.1):
Code: 1000. DB::Exception: Received from localhost:9000. DB::Exception: JSON Exception: error: 1: unexpected end of data. (POCO_EXCEPTION)
Then I create DataLakeCatalog database.
SHOW TABLES will not show those tables, because exceptions are ignored.
Selects from those tables will result in:
SELECT *
FROM `some_namespace.only_created_at7`
Query id: b71d3430-4944-48be-97ec-647fbc525bd4
Elapsed: 0.009 sec.
Received exception from server (version 25.11.1):
Code: 1000. DB::Exception: Received from localhost:9000. DB::Exception: JSON Exception: error: 1: unexpected end of data. (POCO_EXCEPTION)
Trace attached.
Successful read from table in clickhouse.
The error occurs in GlueCatalog::classifyTimestampTZ() when reading Iceberg metadata files from S3. This function is only called for timestamp columns (line 363-368) to determine if a column is timestamp or timestamptz.
2025.11.17 16:58:37.518915 [ 42 ] {b71d3430-4944-48be-97ec-647fbc525bd4} <Error> executeQuery: Poco::Exception. Code: 1000, e.code() = 0, JSON Exception: error: 1: unexpected end of data (version 25.11.1.3421 (official build)) (from 127.0.0.1:52728) (query 1, line 1) (in query: SELECT * FROM `namespace_e2318bf8_c3be_11f0_96aa_e0c26496f172.only_created_at7`;), Stack trace (when copying this message, always include the lines below):
0. Poco::JSON::ParserImpl::checkError() @ 0x000000001fa76d4f
1. Poco::JSON::ParserImpl::handle() @ 0x000000001fa77031
2. Poco::JSON::ParserImpl::handle(String const&) @ 0x000000001fa76b2a
3. Poco::JSON::ParserImpl::parseImpl(String const&) @ 0x000000001fa77490
4. DataLake::GlueCatalog::tryGetTableMetadata(String const&, String const&, DataLake::TableMetadata&) const @ 0x00000000173219ef
5. DB::DatabaseDataLake::tryGetTableImpl(String const&, std::shared_ptr<DB::Context const>, bool, bool) const @ 0x0000000017dae487
6. DB::DatabaseDataLake::tryGetTable(String const&, std::shared_ptr<DB::Context const>) const @ 0x0000000017dae1f0
7. DB::DatabaseCatalog::getTableImpl(DB::StorageID const&, std::shared_ptr<DB::Context const>, std::optional<DB::Exception>*) const @ 0x0000000018a0c4bf
8. DB::DatabaseCatalog::tryGetTable(DB::StorageID const&, std::shared_ptr<DB::Context const>) const @ 0x0000000018a14ef8
9. DB::IdentifierResolver::tryResolveTableIdentifier(DB::Identifier const&, std::shared_ptr<DB::Context const> const&) @ 0x00000000182bbedc
10. DB::QueryAnalyzer::tryResolveIdentifier(DB::IdentifierLookup const&, DB::IdentifierResolveScope&, DB::IdentifierResolveContext) @ 0x0000000018044b79
11. DB::QueryAnalyzer::resolveQuery(std::shared_ptr<DB::IQueryTreeNode> const&, DB::IdentifierResolveScope&) @ 0x0000000018029cf0
12. DB::QueryAnalyzer::resolve(std::shared_ptr<DB::IQueryTreeNode>&, std::shared_ptr<DB::IQueryTreeNode> const&, std::shared_ptr<DB::Context const>) @ 0x000000001802866a
13. DB::QueryAnalysisPass::run(std::shared_ptr<DB::IQueryTreeNode>&, std::shared_ptr<DB::Context const>) @ 0x0000000018027ca4
14. DB::QueryTreePassManager::run(std::shared_ptr<DB::IQueryTreeNode>&) @ 0x000000001807ef23
15. DB::buildQueryTreeAndRunPasses(std::shared_ptr<DB::IAST> const&, DB::SelectQueryOptions const&, std::shared_ptr<DB::Context const> const&, std::shared_ptr<DB::IStorage> const&) (.llvm.14207756650341019090) @ 0x0000000018be163b
16. DB::InterpreterSelectQueryAnalyzer::InterpreterSelectQueryAnalyzer(std::shared_ptr<DB::IAST> const&, std::shared_ptr<DB::Context const> const&, DB::SelectQueryOptions const&, std::vector<String, std::allocator<String>> const&) @ 0x0000000018bdf52a
17. std::unique_ptr<DB::IInterpreter, std::default_delete<DB::IInterpreter>> std::__function::__policy_func<std::unique_ptr<DB::IInterpreter, std::default_delete<DB::IInterpreter>> (DB::InterpreterFactory::Arguments const&)>::__call_func[abi:ne210105]<DB::registerInterpreterSelectQueryAnalyzer(DB::InterpreterFactory&)::$_0>(std::__function::__policy_storage const*, DB::InterpreterFactory::Arguments const&) (.llvm.14207756650341019090) @ 0x0000000018be2ba2
18. DB::InterpreterFactory::get(std::shared_ptr<DB::IAST>&, std::shared_ptr<DB::Context>, DB::SelectQueryOptions const&) @ 0x0000000018b538fc
19. DB::executeQueryImpl(char const*, char const*, std::shared_ptr<DB::Context>, DB::QueryFlags, DB::QueryProcessingStage::Enum, std::unique_ptr<DB::ReadBuffer, std::default_delete<DB::ReadBuffer>>&, std::shared_ptr<DB::IAST>&, std::shared_ptr<DB::ImplicitTransactionControlExecutor>, std::function<void ()>, DB::QueryResultDetails&) @ 0x0000000018fac36a
20. DB::executeQuery(String const&, std::shared_ptr<DB::Context>, DB::QueryFlags, DB::QueryProcessingStage::Enum) @ 0x0000000018fa6efb
21. DB::TCPHandler::runImpl() @ 0x000000001a70fdc0
22. DB::TCPHandler::run() @ 0x000000001a7316d9
23. Poco::Net::TCPServerConnection::start() @ 0x000000001fa0a9c7
24. Poco::Net::TCPServerDispatcher::run() @ 0x000000001fa0ae59
25. Poco::PooledThread::run() @ 0x000000001f9ce4c7
26. Poco::ThreadImpl::runnableEntry(void*) @ 0x000000001f9cca01
27. ? @ 0x0000000000094ac3
28. ? @ 0x00000000001268c0
2025.11.17 16:58:37.519225 [ 42 ] {} <Error> TCPHandler: Code: 1000. DB::Exception: JSON Exception: error: 1: unexpected end of data. (POCO_EXCEPTION), Stack trace (when copying this message, always include the lines below):
0. Poco::JSON::ParserImpl::checkError() @ 0x000000001fa76d4f
1. Poco::JSON::ParserImpl::handle() @ 0x000000001fa77031
2. Poco::JSON::ParserImpl::handle(String const&) @ 0x000000001fa76b2a
3. Poco::JSON::ParserImpl::parseImpl(String const&) @ 0x000000001fa77490
4. DataLake::GlueCatalog::tryGetTableMetadata(String const&, String const&, DataLake::TableMetadata&) const @ 0x00000000173219ef
5. DB::DatabaseDataLake::tryGetTableImpl(String const&, std::shared_ptr<DB::Context const>, bool, bool) const @ 0x0000000017dae487
6. DB::DatabaseDataLake::tryGetTable(String const&, std::shared_ptr<DB::Context const>) const @ 0x0000000017dae1f0
7. DB::DatabaseCatalog::getTableImpl(DB::StorageID const&, std::shared_ptr<DB::Context const>, std::optional<DB::Exception>*) const @ 0x0000000018a0c4bf
8. DB::DatabaseCatalog::tryGetTable(DB::StorageID const&, std::shared_ptr<DB::Context const>) const @ 0x0000000018a14ef8
9. DB::IdentifierResolver::tryResolveTableIdentifier(DB::Identifier const&, std::shared_ptr<DB::Context const> const&) @ 0x00000000182bbedc
10. DB::QueryAnalyzer::tryResolveIdentifier(DB::IdentifierLookup const&, DB::IdentifierResolveScope&, DB::IdentifierResolveContext) @ 0x0000000018044b79
11. DB::QueryAnalyzer::resolveQuery(std::shared_ptr<DB::IQueryTreeNode> const&, DB::IdentifierResolveScope&) @ 0x0000000018029cf0
12. DB::QueryAnalyzer::resolve(std::shared_ptr<DB::IQueryTreeNode>&, std::shared_ptr<DB::IQueryTreeNode> const&, std::shared_ptr<DB::Context const>) @ 0x000000001802866a
13. DB::QueryAnalysisPass::run(std::shared_ptr<DB::IQueryTreeNode>&, std::shared_ptr<DB::Context const>) @ 0x0000000018027ca4
14. DB::QueryTreePassManager::run(std::shared_ptr<DB::IQueryTreeNode>&) @ 0x000000001807ef23
15. DB::buildQueryTreeAndRunPasses(std::shared_ptr<DB::IAST> const&, DB::SelectQueryOptions const&, std::shared_ptr<DB::Context const> const&, std::shared_ptr<DB::IStorage> const&) (.llvm.14207756650341019090) @ 0x0000000018be163b
16. DB::InterpreterSelectQueryAnalyzer::InterpreterSelectQueryAnalyzer(std::shared_ptr<DB::IAST> const&, std::shared_ptr<DB::Context const> const&, DB::SelectQueryOptions const&, std::vector<String, std::allocator<String>> const&) @ 0x0000000018bdf52a
17. std::unique_ptr<DB::IInterpreter, std::default_delete<DB::IInterpreter>> std::__function::__policy_func<std::unique_ptr<DB::IInterpreter, std::default_delete<DB::IInterpreter>> (DB::InterpreterFactory::Arguments const&)>::__call_func[abi:ne210105]<DB::registerInterpreterSelectQueryAnalyzer(DB::InterpreterFactory&)::$_0>(std::__function::__policy_storage const*, DB::InterpreterFactory::Arguments const&) (.llvm.14207756650341019090) @ 0x0000000018be2ba2
18. DB::InterpreterFactory::get(std::shared_ptr<DB::IAST>&, std::shared_ptr<DB::Context>, DB::SelectQueryOptions const&) @ 0x0000000018b538fc
19. DB::executeQueryImpl(char const*, char const*, std::shared_ptr<DB::Context>, DB::QueryFlags, DB::QueryProcessingStage::Enum, std::unique_ptr<DB::ReadBuffer, std::default_delete<DB::ReadBuffer>>&, std::shared_ptr<DB::IAST>&, std::shared_ptr<DB::ImplicitTransactionControlExecutor>, std::function<void ()>, DB::QueryResultDetails&) @ 0x0000000018fac36a
20. DB::executeQuery(String const&, std::shared_ptr<DB::Context>, DB::QueryFlags, DB::QueryProcessingStage::Enum) @ 0x0000000018fa6efb
21. DB::TCPHandler::runImpl() @ 0x000000001a70fdc0
22. DB::TCPHandler::run() @ 0x000000001a7316d9
23. Poco::Net::TCPServerConnection::start() @ 0x000000001fa0a9c7
24. Poco::Net::TCPServerDispatcher::run() @ 0x000000001fa0ae59
25. Poco::PooledThread::run() @ 0x000000001f9ce4c7
26. Poco::ThreadImpl::runnableEntry(void*) @ 0x000000001f9cca01
27. ? @ 0x0000000000094ac3
28. ? @ 0x00000000001268c0
If I create table with PyIceberg, I will not see those exceptions, I will be able to read those tables. Issue appears with spark only.
Jsons generated by spark are completely valid, I didn't see anything weird in glue metadata as well.
Company or project name
No response
Describe what's wrong
When querying Iceberg tables registered in AWS Glue that contain timestamp columns, ClickHouse fails with:
Does it reproduce on the most recent release?
Yes
How to reproduce
In spark:
or
Then I create DataLakeCatalog database.
SHOW TABLES will not show those tables, because exceptions are ignored.
Selects from those tables will result in:
Trace attached.
Expected behavior
Successful read from table in clickhouse.
The error occurs in GlueCatalog::classifyTimestampTZ() when reading Iceberg metadata files from S3. This function is only called for timestamp columns (line 363-368) to determine if a column is timestamp or timestamptz.
Error message and/or stacktrace
Additional context
If I create table with PyIceberg, I will not see those exceptions, I will be able to read those tables. Issue appears with spark only.
Jsons generated by spark are completely valid, I didn't see anything weird in glue metadata as well.