{"record":{"id":"42db4f7564af08f8","repo":"apache/iceberg","slug":"service-failed-s-s","errorCode":null,"errorMessage":"Service failed: %s: %s","messagePattern":"Service failed: (.+?): (.+?)","errorType":"exception","errorClass":"CommitStateUnknownException","httpStatus":500,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/rest/ErrorHandlers.java","lineNumber":236,"sourceCode":"    }\n  }\n\n  /** View commit error handler. */\n  private static class ViewCommitErrorHandler extends DefaultErrorHandler {\n    private static final ErrorHandler INSTANCE = new ViewCommitErrorHandler();\n\n    @Override\n    public void accept(ErrorResponse error) {\n      switch (error.code()) {\n        case 404:\n          throw new NoSuchViewException(\"%s\", error.message());\n        case 409:\n          throw new CommitFailedException(\"Commit failed: %s\", error.message());\n        case 500:\n        case 502:\n        case 503:\n        case 504:\n          throw new CommitStateUnknownException(\n              new ServiceFailureException(\"Service failed: %s: %s\", error.code(), error.message()));\n      }\n\n      super.accept(error);\n    }\n  }\n\n  /** View level error handler. */\n  private static class ViewErrorHandler extends DefaultErrorHandler {\n    private static final ErrorHandler INSTANCE = new ViewErrorHandler();\n\n    @Override\n    public void accept(ErrorResponse error) {\n      switch (error.code()) {\n        case 404:\n          if (NoSuchNamespaceException.class.getSimpleName().equals(error.type())) {\n            throw new NoSuchNamespaceException(\"%s\", error.message());\n          } else {","sourceCodeStart":218,"sourceCodeEnd":254,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/rest/ErrorHandlers.java#L218-L254","documentation":"Thrown by ViewCommitErrorHandler for HTTP 500/502/503/504 on a view commit. Iceberg wraps a ServiceFailureException in CommitStateUnknownException because the server may or may not have applied the commit — the final state is indeterminate. The caller must not blindly retry as a fresh create; it must reconcile the actual view state first.","triggerScenarios":"Server-side outages, gateway timeouts, or load-balancer 5xx responses during a view commit request.","commonSituations":"REST service restart or rolling deploy mid-commit; upstream proxy/gateway 502-504; server overload returning 500.","solutions":["Treat the commit as unknown: reload the view and check whether the change actually landed before retrying","Retry the commit only after confirming it was not applied (idempotent retry with same requirements)","Check REST service health/logs for the corresponding 5xx cause","Add client retry with backoff for transient 502/503/504, and reconcile on 500"],"exampleFix":"// before\ncatalog.updateView(viewId).setSchema(schema).commit(); // 503 -> CommitStateUnknownException\n// after\ntry {\n  catalog.updateView(viewId).setSchema(schema).commit();\n} catch (CommitStateUnknownException e) {\n  View loaded = catalog.loadView(viewId);\n  if (!applied(loaded, schema)) {\n    catalog.updateView(viewId).setSchema(schema).commit();\n  }\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  updateView.commit();\n} catch (CommitStateUnknownException e) {\n  View loaded = catalog.loadView(viewId);\n  if (!applied(loaded)) {\n    updateView.commit(); // safe retry only after confirming not applied\n  }\n}","preventionTips":["Never assume a commit failed on 5xx — always reconcile state first","Add backoff retry for 502/503/504 with a final state check","Monitor REST service health to correlate CommitStateUnknownException with outages"],"tags":["rest-catalog","view","commit","server-error","unknown-state"],"backgroundTag":"http-error-response","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"}