Zero-copy and mirroring were supposed to be teammates. Iceberg metadata became the sticking point.
Snowflake's zero-copy clones let us create table copies without duplicating the existing data files. In our Fabric mirroring workflow, the Iceberg source also needed to convert into virtual Delta metadata for consumption.
The source table worked in Snowflake. Fabric's conversion log said BAD_METADATA. The data was present; the clash was in how the table's metadata was handled.
I got all eight tables in this test converting again with a controlled insert, delete, and retry. The temporary row was removed. The business data ended where it started—but the conversion recovered.
Here's what made this a new gotcha.
Zero-copy still needs the right metadata
Iceberg stores data in files and uses metadata to describe which files make up a table. Think of the metadata as its map.
In our setup, Fabric accessed the Iceberg source through a shortcut and generated virtual Delta metadata for consumption. The source being readable in Snowflake didn't prove that this conversion had succeeded.
The diagnostic reported competing metadata sets: a low-version metadata file had been modified more recently than a higher-version file.
The newest file wasn't necessarily the latest version of the production table.
A clone brings another table identity
We had cloned the source tables into other databases. In the cases inspected, source and clone metadata paths led into the same metadata directory.
Cloning doesn't need to change the production rows to create new metadata. Snowflake gives an Iceberg clone distinct metadata, including its own table-uuid. It shares underlying storage, but represents a separate table. Snowflake documents this behavior.
That combination matters for quiet reference tables: production may not have had a recent write, while a newer clone has introduced metadata for another table identity.
Our working explanation is that clone metadata interfered with Fabric's discovery of the intended source metadata. Working tables also had clones, so clone presence alone wasn't a diagnosis; the exact file-selection mechanism remains under investigation.
The recovery I tested
For the affected source tables, I:
- Inserted a temporary row.
- Deleted that exact row.
- Retried the Fabric conversion.
Fabric conversion succeeded for all eight tested tables.
I checked the metadata after the insert and delete. Each of the eight tables advanced by two metadata versions, and the production metadata files had the newest S3 modification timestamps. The writes changed the metadata even though the temporary rows were removed.
Microsoft's guidance also describes committing a source change to trigger another conversion attempt. OneLake troubleshooting.
This is a targeted recovery, not a permanent fix. A temporary row needs a verified unused identifier, and downstream change consumers may still see the insert and delete. I wouldn't automate dummy writes across production.
What to check on the next failure
- Read
latest_conversion_log.txtunder the shortcut's virtual_delta_logfolder. - Compare the source and known clone metadata paths, table identities, and actual storage modification times.
- After a retry, check conversion status and validate the intended table state through Fabric.
LAST_ALTERED can help prioritize candidates, but it isn't an S3 file timestamp or proof that two tables are clones. It includes DDL, DML, and background metadata operations. Snowflake's TABLES view notes.
Microsoft documents multiple metadata sets in one Iceberg folder as a conversion limitation. Its cleanup example concerns dropped and recreated tables; don't apply that cleanup blindly to files used by live clones.
The lasting fix needs to make the intended table metadata unambiguous to the consumer. For now, the tested recovery gives us a way forward while that is investigated.
Zero-copy can share the files. Iceberg metadata still has to tell the reader which table those files belong to.
Previous gotchas: Part 1 · Part 2.
Have you seen a source table stay readable while its Fabric conversion failed?













