{"record":{"id":"a58783f377e1144e","repo":"apache/iceberg","slug":"cannot-parse-order-parser-is-not-an-iceberg-exten-a58783","errorCode":null,"errorMessage":"Cannot parse order: parser is not an Iceberg ExtendedParser","messagePattern":"Cannot parse order: parser is not an Iceberg ExtendedParser","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/ExtendedParser.java","lineNumber":67,"sourceCode":"      return direction;\n    }\n\n    public NullOrder nullOrder() {\n      return nullOrder;\n    }\n  }\n\n  static List<RawOrderField> parseSortOrder(SparkSession spark, String orderString) {\n    ExtendedParser extParser = findParser(spark.sessionState().sqlParser(), ExtendedParser.class);\n    if (extParser != null) {\n      try {\n        return extParser.parseSortOrder(orderString);\n      } catch (AnalysisException e) {\n        throw new IllegalArgumentException(\n            String.format(\"Unable to parse sortOrder: %s\", orderString), e);\n      }\n    } else {\n      throw new IllegalStateException(\n          \"Cannot parse order: parser is not an Iceberg ExtendedParser\");\n    }\n  }\n\n  private static <T> T findParser(ParserInterface parser, Class<T> clazz) {\n    ParserInterface current = parser;\n    while (current != null) {\n      if (clazz.isInstance(current)) {\n        return clazz.cast(current);\n      }\n\n      current = getNextDelegateParser(current);\n    }\n\n    return null;\n  }\n\n  private static ParserInterface getNextDelegateParser(ParserInterface parser) {","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/ExtendedParser.java#L49-L85","documentation":"parseSortOrder first locates the session's SQL parser and requires it to be (or unwrap to) an Iceberg ExtendedParser. If the active parser is a plain Spark parser (Iceberg extensions not registered), it throws IllegalStateException because sort-order expressions cannot be parsed without Iceberg's SQL extensions.","triggerScenarios":"Running Iceberg procedures like rewrite_data_files with sort strategy in a SparkSession configured without spark.sql.extensions=org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions, or a session where another extension replaced the parser.","commonSituations":"Notebooks or spark-submit jobs missing the extensions config; using a shared SparkSession initialized by another framework (e.g. Livy, Spark Connect) without Iceberg extensions; conflicting multiple sql.extensions values overwriting Iceberg's.","solutions":["Configure the session with --conf spark.sql.extensions=org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions before running the procedure","If multiple extensions are needed, comma-separate them so Iceberg's is not overwritten: spark.sql.extensions=a.B,c.D,...,org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions","Verify with: SELECT ... — or inspect spark.sessionState.sqlParser; restart the session after fixing config (extensions cannot be reliably applied to an existing session)"],"exampleFix":"// before\nSparkSession.builder().appName(\"app\").getOrCreate() // no extensions\n// after\nSparkSession.builder().appName(\"app\")\n  .config(\"spark.sql.extensions\", \"org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions\")\n  .getOrCreate()","handlingStrategy":"validation","validationCode":"// ensure Iceberg extensions are configured before using Iceberg procedures\nString ext = spark.conf().get(\"spark.sql.extensions\", \"\");\nif (!ext.contains(\"IcebergSparkSessionExtensions\")) {\n  throw new IllegalStateException(\"Set spark.sql.extensions to include IcebergSparkSessionExtensions\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  callRewriteDataFiles(sortOrder);\n} catch (IllegalStateException e) {\n  if (e.getMessage().contains(\"parser is not an Iceberg ExtendedParser\")) {\n    // restart session with spark.sql.extensions configured\n  } else { throw e; }\n}","preventionTips":["Always set spark.sql.extensions=org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions","Comma-separate multiple extensions; never overwrite Iceberg's entry","Verify parser setup when sessions are created by frameworks (Livy, Spark Connect)"],"tags":["spark","configuration","sql-extensions","parser"],"backgroundTag":"missing-required-config","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}