{"record":{"id":"ebb3460bb66a36de","repo":"apache/iceberg","slug":"cannot-rename-s-to-s-another-content-of-type-s","errorCode":null,"errorMessage":"Cannot rename %s to %s. Another content of type %s with same name already exists","messagePattern":"Cannot rename (.+?) to (.+?)\\. Another content of type (.+?) with same name already exists","errorType":"exception","errorClass":"AlreadyExistsException","httpStatus":409,"severity":"error","filePath":"nessie/src/main/java/org/apache/iceberg/nessie/NessieIcebergClient.java","lineNumber":523,"sourceCode":"      // safe than sorry.\n      throw new CommitStateUnknownException(ex);\n    }\n    // Intentionally just \"throw through\" Nessie's HttpClientException here and do not \"special\n    // case\"\n    // just the \"timeout\" variant to propagate all kinds of network errors (e.g. connection reset).\n    // Network code implementation details and all kinds of network devices can induce unexpected\n    // behavior. So better be safe than sorry.\n  }\n\n  private static void validateToContentForRename(\n      TableIdentifier from, TableIdentifier to, IcebergContent existingToContent) {\n    if (existingToContent != null) {\n      if (existingToContent.getType() == Content.Type.ICEBERG_VIEW) {\n        throw new AlreadyExistsException(\"Cannot rename %s to %s. View already exists\", from, to);\n      } else if (existingToContent.getType() == Content.Type.ICEBERG_TABLE) {\n        throw new AlreadyExistsException(\"Cannot rename %s to %s. Table already exists\", from, to);\n      } else {\n        throw new AlreadyExistsException(\n            \"Cannot rename %s to %s. Another content of type %s with same name already exists\",\n            from, to, existingToContent.getType());\n      }\n    }\n  }\n\n  private static void validateFromContentForRename(\n      TableIdentifier from, Content.Type type, IcebergContent existingFromContent) {\n    if (existingFromContent == null) {\n      if (type == Content.Type.ICEBERG_VIEW) {\n        throw new NoSuchViewException(\"View does not exist: %s\", from);\n      } else if (type == Content.Type.ICEBERG_TABLE) {\n        throw new NoSuchTableException(\"Table does not exist: %s\", from);\n      } else {\n        throw new RuntimeException(\"Cannot perform rename for content type: \" + type);\n      }\n    } else if (existingFromContent.getType() != type) {\n      throw new RuntimeException(","sourceCodeStart":505,"sourceCodeEnd":541,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/nessie/src/main/java/org/apache/iceberg/nessie/NessieIcebergClient.java#L505-L541","documentation":"The fallback branch of validateToContentForRename: if the destination identifier holds existing content that is neither an Iceberg table nor an Iceberg view (another content type known to Nessie, e.g. other registered content kinds), the rename throws AlreadyExistsException naming the actual type. This prevents cross-type overwrites for content Nessie tracks but Iceberg does not model.","triggerScenarios":"renameTable/renameView where fetchContent(to) returns non-null IcebergContent whose getType() is neither ICEBERG_TABLE nor ICEBERG_VIEW — the destination key holds other Nessie-managed content.","commonSituations":"Nessie namespaces host non-Iceberg content (other engines/models registered at the same content key); a mixed-workload Nessie repository where identifiers collide across content kinds; upgraded/patched content model introducing types the Iceberg client version doesn't recognize.","solutions":["Pick a destination identifier free of any content — verify via Nessie API getEntriesFor that 'to' has no entry.","Remove the foreign content at the destination key through the tool that owns it, then rerun the rename.","Upgrade the Iceberg-Nessie integration so newer content types are mapped/handled instead of hitting the fallback.","Separate Iceberg content into its own Nessie namespace/repo to avoid cross-type key collisions."],"exampleFix":"// before\ncatalog.renameTable(t, TableIdentifier.of(\"ns\",\"shared\")); // 'ns.shared' holds foreign content\n// after\nContent dest = nessieApi.getContent().refName(\"main\").key(ContentKey.of(\"ns\",\"shared\")).get()\n    .get(ContentKey.of(\"ns\",\"shared\"));\nif (dest == null) {\n  catalog.renameTable(t, TableIdentifier.of(\"ns\",\"shared\"));\n}","handlingStrategy":"validation","validationCode":"// via Nessie API: ensure destination key holds no content of any kind\nMap<ContentKey, Content> m = nessieApi.getContent()\n    .refName(refName).key(ContentKey.of(to.namespace().levels())).get();\nboolean destFree = !m.containsKey(ContentKey.of(to.namespace().levels()));","typeGuard":null,"tryCatchPattern":"try {\n  catalog.renameTable(from, to);\n} catch (AlreadyExistsException e) {\n  if (String.valueOf(e.getMessage()).contains(\"Another content of type\")) {\n    // foreign content at destination; route to the owning tool or choose another name\n    handleForeignContentCollision(to, e);\n  } else throw e;\n}","preventionTips":["In mixed-workload Nessie repos, reserve namespaces per content kind.","Check Nessie content entries (all types), not just Iceberg tables, before renames.","Upgrade the Iceberg-Nessie client when new Nessie content types are introduced.","Keep Iceberg content isolated in dedicated repos or namespace trees."],"tags":["nessie","catalog","rename","already-exists","content-type"],"backgroundTag":"file-already-exists","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"}