Releases
Apache Iceberg Go follows the standard Apache release process. Releases are cut from main, voted on by the Apache Iceberg PMC, and published as signed source tarballs to https://downloads.apache.org/iceberg/ and as Go module versions tagged vX.Y.Z.
Latest release
Using a release
Pin a tagged version directly with Go modules:
go get github.com/apache/iceberg-go@vX.Y.Z
To track main, use @main instead of a version tag.
Release notes
Per-release notes (highlights, breaking changes, contributors) are published on the GitHub Releases page. Iceberg Go does not maintain a curated CHANGELOG.md in the repository; the GitHub Releases page is the canonical source.
Unreleased compatibility notes
-
Catalog capabilities split into narrower interfaces.
catalog.Catalognow embedsTableCatalogandNamespaceCatalogwith unchanged table and namespace methods.Name() stringis now required, breaking third-party catalogs and test fakes.ViewCatalogis optional (REST and Hive), while REST also implementsUpdatableViewCatalogforUpdateView. Usecatalog.As[T](cat)and theUnwrap() Catalogconvention to discover optional capabilities through decorators. Future capabilities should use optional interfaces rather than extendingCatalog. -
ReplaceFilesWithDeleteFilesremoved. For delete-file replacements, usetx.NewRewrite(snapshotProps), callDeleteFilefor each source file andAddDeleteFileWithDataSequenceNumberfor each replacement, then commit the builder. Rewrites record areplacesnapshot instead ofoverwrite. The five-argumentReplaceFilesAPI is unchanged and remains available for compaction and delete-file removals. -
Path-based data-file addition renamed. Replace
Transaction.AddFileswithAddDataFilesByPath,AddFilesOptionwithAddDataFilesByPathOption, andWithAddFilesConcurrencywithWithAddDataFilesByPathConcurrency. Behavior is unchanged. -
Manifest builder constructor renamed. Replace
iceberg.NewManifestFile(...)withiceberg.NewManifestBuilder(...). It still returns aManifestBuilder. -
Manifest sequence APIs use explicit names.
ManifestBuilder.SequenceNumandManifestFile.SequenceNumbecomeSequenceNumber, andManifestFile.MinSequenceNumbecomesMinSequenceNumber.ManifestEntryBuilder.SequenceNumandManifestEntry.SequenceNumbecomeDataSequenceNumber.FileSequenceNumbecomesFileSequenceNumberfor entries and their builder. Avro and JSON field names are unchanged. -
View and UDF metadata builder constructors are infallible.
view.NewMetadataBuilderandudf.NewMetadataBuildernow return only a builder instead of(builder, error); remove error handling at call sites. -
Table metadata getter renamed. Replace
table.Metadata.Version()withtable.Metadata.FormatVersion(), consistent with Iceberg Java and Go view/UDF metadata. Metadata JSON is unchanged. -
Snapshot ref type field renamed. Replace
table.SnapshotRef.SnapshotRefTypewithtable.SnapshotRef.Type. The JSON field is still"type". -
As-of snapshot lookups now use inclusive timestamps. Replace
tbl.SnapshotAsOf(timestampMs, true)withtbl.SnapshotAsOf(timestampMs). The method always selects the latest snapshot at or before the timestamp, matching Java Iceberg'sSnapshotUtil.nullableSnapshotIdAsOfTime. For strict-before lookup, useSnapshotLogEntryAsOf(tbl.Metadata().SnapshotLogs(), timestampMs, false). -
Snapshot timestamp property key corrected.
PropertyCurrentSnapshotTimestampnow usescurrent-snapshot-timestamp-ms. The oldcurrent-snapshot-timestampspelling is no longer reserved and remains usable as a custom property. -
FileIO open and remove take a context.
io.IO.Openandio.IO.Removenow take acontext.Contextfirst argument, so customio.IOimplementations must add it.maintenance.WithCleanupDeleteFuncnow takesfunc(context.Context, string) error. -
Hadoop catalog construction takes a context.
hadoop.NewCatalog(name, warehouse, props)becomeshadoop.NewCatalog(ctx, name, warehouse, props). The context bounds filesystem setup; the catalog's filesystem keeps its values but not its cancellation. -
Config loading reports errors.
config.LoadConfignow returns([]byte, error), andconfig.LoadConfigFileis removed; callLoadConfiginstead. A missing default~/.iceberg-go.yamlstill returns no data and no error. -
Branch transactions return initialization errors.
Table.NewTransactionOnBranch(branch)now returns(*Transaction, error), andTable.NewTransactionOnBranchWithErroris removed. UseNewTransactionOnBranchand handle its error. -
Schema JSON constructor uses the Go initialism. Replace
iceberg.NewSchemaFromJsonFieldswithiceberg.NewSchemaFromJSONFields. -
AWS identifiers use the Go initialism.
glue.AwsProperties,glue.WithAwsConfigandglue.WithAwsPropertiesbecomeglue.AWSProperties,glue.WithAWSConfigandglue.WithAWSProperties;sigv4.WithAwsConfigbecomessigv4.WithAWSConfig;utils.WithAwsConfigandutils.GetAwsConfigbecomeutils.WithAWSConfigandutils.GetAWSConfig; andconfig.CatalogConfig.AwsProfilebecomesAWSProfile. Theaws-profileYAML key is unchanged. -
KMS factory registration now takes a context. Change
encryption.KMSFactoryimplementations to accept(context.Context, map[string]string)instead of only properties, and callencryption.LoadKeyManagementClient(ctx, props)instead ofLoadKeyManagementClient(props). The existing globalRegisterKMS,UnregisterKMS, andGetRegisteredKMSNamesfunctions still use the default registry;RegisterKMSstill panics for invalid registrations. Useencryption.MustRegisterKMSfor provider initialization. For isolated registrations, createregistry := encryption.NewKMSRegistry()after importing any KMS providers and callregistry.Register,registry.Load(ctx, props),registry.Names, orregistry.Unregister. New registries snapshot the global registrations; subsequent changes do not propagate. -
Name-mapping child lookup renamed. Replace
MappedField.GetField(name)withMappedField.FindFieldByName(name), which returns(*MappedField, bool). The new method returns a pointer to the actual child field rather than a copy, and reports a missing name withfalse. -
Data file block size setter removed.
iceberg.DataFileBuilder.BlockSizeInBytesis removed. New v1 manifests use the Avro schema's 64 MiB default when the field is unset. V2/v3 omit this deprecated field, and legacy v1 values remain readable. -
View creation APIs take a named SQL representation.
view.NewVersionFromSQL,view.CreateView,view.CreateViewWithIOProperties, andsql.Catalog.CreateViewnow accept aview.Representation{SQL: sql, Dialect: dialect}instead of positional SQL/dialect strings. The dialect is required; Hive preserves the selected representation's dialect. -
View SQL representation construction uses named fields. Replace
view.NewRepresentation(sql, dialect)withview.NewRepresentation(view.Representation{SQL: sql, Dialect: dialect}). Serialized JSON is unchanged. -
Hive views keep the caller's view version.
hive.Catalog.CreateViewnow stores every representation, the summary, the default namespace anddefault-catalogas passed, instead of one representation withdefault-catalogset to"hive". -
Reserved table properties now use a read-only API. Replace references to
table.ReservedPropertieswithtable.ReservedProperties(). The function returns a fresh slice, so callers cannot change metadata validation by modifying it. -
Fixed and decimal constructors return errors.
iceberg.FixedTypeOfandiceberg.DecimalTypeOfnow return(type, error)instead of panicking for invalid inputs. UseMustFixedTypeOforMustDecimalTypeOfonly for known-valid values. -
SQL UDF representations now use struct literals. The
udf.NewSQLRepresentation(dialect, sql)function, available since v0.7.0, is removed. Useudf.SQLRepresentation{Dialect: "trino", SQL: "x + 1"}instead. Empty fields and duplicate dialects are checked during metadata validation; serialized JSON is unchanged. -
Filesystem adapter construction consolidated. Replace
io.FSPreProcName(fsys, fn)withio.FS(fsys, io.WithNamePreprocessor(fn)). Plainio.FS(fsys)remains supported. -
Table purge is required on catalogs. The
catalog.Cataloginterface now embedscatalog.PurgeableCatalog; every custom catalog implementation must providePurgeTable(ctx, identifier) error. The narrowcatalog.PurgeableTableinterface is renamed tocatalog.PurgeableCatalog. Built-in purge behavior is unchanged. -
Unify statistics blob types with Puffin. Replace
table.BlobTypewithpuffin.BlobTypewhen constructingtable.BlobMetadata. Replacetable.BlobTypeApacheDatasketchesThetaV1withpuffin.BlobTypeDataSketchesThetaandtable.BlobTypeDeletionVectorV1withpuffin.BlobTypeDeletionVector. Usepuffin.BlobType.IsKnown()to identify the types defined by the Puffin specification; the redundanttable.BlobType.IsValid()method is removed. Unknown non-empty blob type names still round-trip through table metadata. -
View representation field uses the Go SQL initialism. Replace
view.Representation.Sqlwithview.Representation.SQL. Serialized view metadata still uses thesqlJSON field. -
Orphan cleanup results now expose only
OrphanFiles. Replaceresult.OrphanFileLocationswithresult.OrphanFiles(each entry hasPathandSizeBytes).OrphanCleanupPlan.Files()still provides path-only lists during planning. -
Catalog identifier helper renamed.
catalog.TableNameFromIdentis removed. Usecatalog.ObjectNameFromIdentfor tables, views, and functions. -
Substrait expression conversion no longer takes case sensitivity.
substrait.ConvertExpr(schema, expression, caseSensitive)becomessubstrait.ConvertExpr(schema, expression). Case sensitivity remains part of expression binding. -
Transform formatting requires the result type and uses the Java-aligned method name.
Transform.ToHumanStr(value)andTransform.ToHumanStrType(resultType, value)are removed. UseTransform.ToHumanString(resultType, value)to format partition values, including timestamps with time zones. -
Catalogs now require cleanup. The
catalog.Cataloginterface includesClose() error. Custom catalog implementations must provideClose, and callers should close catalog instances after use.catalog.Closeris removed. Replacecat.(catalog.Closer)checks withdefer cat.Close();catalog.Catalogalready implementsio.Closer, so no type assertion is needed. -
Puffin writer property setter renamed.
puffin.Writer.AddPropertiesis nowpuffin.Writer.SetProperties. Repeated calls still merge keys; useClearPropertiesto clear custom properties before finishing. -
Orphan file cleanup moved to
table/maintenance. The orphan-cleanup and file-purge API is no longer ontable.Table; it now lives in thetable/maintenancepackage as free functions that take the table as their first argument (matchingtable/compaction). For example,tbl.DeleteOrphanFiles(ctx, ...)becomesmaintenance.DeleteOrphanFiles(ctx, tbl, ...). Becausetable/maintenanceimportstable(and not the reverse), this cannot be offered as a deprecation shim ontable.Tablewithout an import cycle, so callers must switch to the new package. The following moved fromtabletotable/maintenance:- Functions (now free functions taking
*table.Table):DeleteOrphanFiles,PlanOrphanFiles,ExecuteOrphanCleanup,PurgeFiles. - Types:
OrphanCleanupOption,OrphanCleanupResult,OrphanFile,OrphanCleanupPlan,PrefixMismatchMode. - Constants:
PrefixMismatchError,PrefixMismatchIgnore,PrefixMismatchDelete. - Option constructors:
WithCleanupLocation,WithCleanupFilesOlderThan,WithCleanupDryRun,WithCleanupDeleteFunc,WithCleanupMaxConcurrency,WithPrefixMismatchMode,WithEqualSchemes,WithEqualAuthorities. The four generic names (WithLocation,WithFilesOlderThan,WithDryRun,WithDeleteFunc) gained theWithCleanupprefix for consistency.
Relatedly, the previously unexported
isGCEnabledis nowtable.IsGCEnabled, so the new package can gate destructive operations on thegc.enabledtable property. - Functions (now free functions taking
-
Data-file replacement methods renamed. Use
ReplaceDataFilesByPathfor string paths. UseReplaceDataFilesfor prebuiltDataFilevalues instead ofReplaceDataFilesWithDataFiles. -
maintenance.PurgeFiles(previouslyTable.PurgeFiles) now callsIO.Removeconcurrently, with up to 32 calls in flight, when the filesystem does not implementBulkRemovableIO. Custom IO implementations, including those registered withio.Register, must makeRemovesafe for concurrent use and synchronize any shared mutable state. The bulk deletion path is unchanged. -
Partition and sort source accessors renamed. Replace
PartitionField.SourceID()andSortField.SourceID()withFirstSourceID(). Their behavior and serialized fields are unchanged. -
Row-lineage column predicate renamed. Use
iceberg.IsRowLineageColumninstead oficeberg.IsMetadataColumnto identify_row_idand_last_updated_sequence_number. Useiceberg.IsReservedFieldIDto check the full reserved metadata field ID range. -
File writes and directory walks now take an operation context. Update
WriteFileIOandListableIOimplementations and calls toCreate,WriteFile, andWalkDirto passcontext.Context; cloud writes and listings use it for cancellation. -
In and NotIn follow SQL semantics for NULL. A multi-valued
NotIn,NOT(In(...))andNOT(NotIn(...))no longer match rows where the column is NULL, consistent withNotEqual. A predicate under NOT on a column missing from an older data file no longer matches every row of that file; those rows match as a stored NULL would. Java'sEvaluatorstill matches NULL fornotEqandnotIn, see apache/iceberg#18701.
Verifying and producing releases
If you are validating an RC or cutting a new release, see:
- Verify a release - what to do when a
[VOTE]thread is posted ondev@iceberg.apache.org. - How to release - PMC/committer process for cutting an RC and publishing.