{"record":{"id":"6406bfe175375673","repo":"apache/iceberg","slug":"cannot-use-catalog-plugin-name-not-a-procedure","errorCode":null,"errorMessage":"Cannot use catalog ${plugin.name}: not a ProcedureCatalog","messagePattern":"Cannot use catalog (.+?): not a ProcedureCatalog","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"spark/v3.5/spark-extensions/src/main/scala/org/apache/spark/sql/catalyst/analysis/ResolveProcedures.scala","lineNumber":189,"sourceCode":"      case param =>\n        val normalizedName = param.name.toLowerCase(Locale.ROOT)\n        ProcedureParameter.optional(normalizedName, param.dataType)\n    }\n  }\n\n  private def normalizeArgs(args: Seq[CallArgument]): Seq[CallArgument] = {\n    args.map {\n      case a @ NamedArgument(name, _) => a.copy(name = name.toLowerCase(Locale.ROOT))\n      case other => other\n    }\n  }\n\n  implicit class CatalogHelper(plugin: CatalogPlugin) {\n    def asProcedureCatalog: ProcedureCatalog = plugin match {\n      case procedureCatalog: ProcedureCatalog =>\n        procedureCatalog\n      case _ =>\n        throw new AnalysisException(s\"Cannot use catalog ${plugin.name}: not a ProcedureCatalog\")\n    }\n  }\n}\n","sourceCodeStart":171,"sourceCodeEnd":193,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v3.5/spark-extensions/src/main/scala/org/apache/spark/sql/catalyst/analysis/ResolveProcedures.scala#L171-L193","documentation":"Thrown by ResolveProcedures' CatalogHelper.asProcedureCatalog when the catalog resolved from a CALL statement is an Iceberg CatalogPlugin but does not implement the ProcedureCatalog interface, meaning it cannot expose or load procedures.","triggerScenarios":"CALL some_catalog.system.some_procedure(...) where some_catalog is a catalog implementation (e.g. a generic Hive/Hadoop/JDBC catalog) that lacks ProcedureCatalog support.","commonSituations":"Pointing CALL at the wrong catalog (e.g. session/default catalog instead of the Iceberg catalog); using a catalog plugin version that predates procedure support; misconfigured spark.sql.default-catalog.","solutions":["Prefix the CALL with an Iceberg catalog that supports procedures (e.g. CALL my_iceberg_catalog.system.rewrite_data_files(...))","Check which catalog the procedure belongs to and set/qualify accordingly — not all catalogs implement ProcedureCatalog","Upgrade the catalog implementation to an Iceberg version that supports procedures if you expected it to"],"exampleFix":"// before\nCALL spark_catalog.system.rewrite_data_files(table => 'db.t')\n// after\nCALL iceberg_catalog.system.rewrite_data_files(table => 'db.t')","handlingStrategy":"validation","validationCode":"val plugin = spark.sessionState.catalogManager.catalog(catalogName)\nrequire(plugin.isInstanceOf[ProcedureCatalog],\n  s\"catalog $catalogName does not support procedures\")","typeGuard":null,"tryCatchPattern":"try { spark.sql(callSql) } catch { case e: AnalysisException if e.getMessage.contains(\"not a ProcedureCatalog\") => // retarget CALL at an Iceberg catalog }","preventionTips":["Always qualify CALL statements with a procedure-capable Iceberg catalog name","Check the default catalog setting (spark.sql.default-catalog) when using unqualified CALLs","Confirm the catalog implementation supports procedures before registering it for CALL usage"],"tags":["spark","sql","catalog","call-procedure"],"backgroundTag":"unsupported-operation","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}