apache/iceberg · error · IllegalStateException
Failed to update: %d of %d succeeded
Error message
Failed to update: %d of %d succeeded
What it means
updateProperties() executes JdbcUtil.updatePropertiesStatement expecting one updated row per property. If fewer rows are updated it throws IllegalStateException "Failed to update: %d of %d succeeded" — the UPDATE affected fewer rows than properties supplied, indicating inconsistent catalog rows (e.g., a property row was deleted concurrently).
Source
Thrown at core/src/main/java/org/apache/iceberg/jdbc/JdbcCatalog.java:878
}
private boolean updateProperties(Namespace namespace, Map<String, String> properties) {
String namespaceName = JdbcUtil.namespaceToString(namespace);
Stream<String> caseArgs =
properties.entrySet().stream()
.flatMap(entry -> Stream.of(entry.getKey(), entry.getValue()));
Stream<String> whereArgs =
Stream.concat(Stream.of(catalogName, namespaceName), properties.keySet().stream());
String[] args = Stream.concat(caseArgs, whereArgs).toArray(String[]::new);
int updatedRecords = execute(JdbcUtil.updatePropertiesStatement(properties.size()), args);
if (updatedRecords == properties.size()) {
return true;
}
throw new IllegalStateException(
String.format(
Locale.ROOT,
"Failed to update: %d of %d succeeded",
updatedRecords,
properties.size()));
}
private boolean deleteProperties(Namespace namespace, Set<String> properties) {
String namespaceName = JdbcUtil.namespaceToString(namespace);
String[] args =
Stream.concat(Stream.of(catalogName, namespaceName), properties.stream())
.toArray(String[]::new);
return execute(JdbcUtil.deletePropertiesStatement(properties), args) > 0;
}
@Override
protected Map<String, String> properties() {View on GitHub (pinned to 86d9c8fc54)
Solutions
- Retry setProperties; missing keys may need insertProperties instead of update
- Reconcile by reading loadNamespaceMetadata and setting only keys that exist for update
- Avoid concurrent writers to the same namespace properties
- Check for earlier "Failed to insert" failures leaving partial state and repair those rows
Example fix
// before
catalog.setProperties(ns, props);
// after
Map<String, String> existing = catalog.loadNamespaceMetadata(ns);
if (existing.keySet().containsAll(props.keySet())) {
catalog.setProperties(ns, props);
} else {
throw new IllegalStateException("Cannot update missing properties: " + props.keySet());
} Defensive patterns
Strategy: validation
Validate before calling
Map<String, String> existing = catalog.loadNamespaceMetadata(ns);
if (!existing.keySet().containsAll(props.keySet())) {
throw new IllegalStateException("Cannot update: some keys missing in catalog");
}
catalog.setProperties(ns, props); Try / catch
try {
catalog.setProperties(ns, props);
} catch (IllegalStateException e) {
if (e.getMessage().startsWith("Failed to update")) {
LOG.error("Partial property update; re-reading catalog state");
throw e;
} else throw e;
} Prevention
- Only update keys that already exist; insert missing keys first
- Serialize property updates per namespace across clients
- Repair partial state left by earlier insert failures before updating
- Be aware some JDBC drivers report update counts differently
When it happens
Trigger: setProperties where some property keys are missing from the catalog table (deleted concurrently or partially inserted earlier), or the catalog schema's key constraints differ; the UPDATE then matches fewer rows than requested.
Common situations: Race with another client dropping the same namespace properties; recovery from a prior partial insert; databases where update counts don't match row matches (depending on driver settings).
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Failed to insert: %d of %d succeeded
- Interrupted in call to initialize
- Interrupted in SQL command
- Interrupted in SQL query
- Failed to load table %s from catalog %s: dropped by another
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/5acec77dc0de4a8c.
Report an issue: GitHub.